尤川豪   ·  5年前
445 貼文  ·  275 留言

開發一個中型 React 應用的流程經驗

需要實作一個活動管理的新增介面,模仿 Eventbrite 的新增介面

此介面包含

  • 多項基本資訊
  • 場次設定(單場,或是每日、每週、自訂多場)
  • 票券設定(單人、多人、團體)

算是滿複雜、互動性滿高的一個介面。所以試圖設計一套前端開發流程,維持速度、同時有盡量高的擴充性、重用性、可維護性。state 以 redux 做管理。


開發流程

1. 用純 React 把各個小元件寫出來

local state,將互動功能做完。這些小元件非常獨立。然後用一個 App 元件去包住這些小元件來完成整個頁面。

需要的話,App 元件可以再切分成幾個區塊元件。

2. 把小元件的 state 拉高,到外面

這些 state 攸關 business logic,最終需要進 redux。

把小元件的 state 拉出來到外面,小元件一律透過 props 與外部互動,不需要知道外部如何儲存 state 的。

最無腦的作法,設計成只吃兩個 props,value 與 onChange。value 吃進 state,onChange 通知外部更新後的 state。

小元件內部可以有更多小元件,但以最上層的元件作為介面與外部互動,value 與 onChange 就在它身上。

3. App 元件整理好各小元件的 state

把所有小元件拉出來的 state 在 App 元件中安置好,需要的話,安置在 App 元件底下切出的區塊元件也可以。

整理好之後,整個頁面的互動操作已經可用,外觀幾乎已完成。

4. 把 App 的 state 移進 redux

把 App 元件給 connect。需要的話,App 元件底下切出的區塊元件也可以 connect。

redux 內的結構設計則自由發揮。總之 state 移進 redux 之後,整個頁面需要發 ajax 時,取用 state 方便許多。


相關 reducer 的資料結構設計

各個小元件是互相獨立的,state 不應該放在一起(cohesion 會降低)

把相關的 state 整理在一起,做成多個 reducer,最後用 combineReducers 合併。

const reducer = combineReducers({
  basicInfo,
  scheduleDates,
  createTickets,
});

這些 state 的資料結構不需要跟 React 的那些 UI 元件結構一模一樣對應。但大概會很相似就是了。

React 的那些 UI 元件結構放在一起看時,方便理解為主。

這些 state 的資料結構放在一起看時,方便理解為主。


結論

留意要給 React component 跟最後做出來的多個 reducer 都保留重用空間。

小元件都做成只吃 props 與外部互動了,重用性不會低。

對應的小 reducer 也要保留彈性空間。

檔案結構上或許無法從一開始清楚分出哪些要獨立出來重用、哪些不適合。但至少檔案內的程式碼盡量獨立。

疑問與反省

  • 優點:各 UI 元件很獨立、各 reducer 都小小的且獨立專注於特定 state
  • 缺點:因為是最後才去思考 redux,導致「更新資料的商業邏輯」幾乎全在 React component 內已經寫好了

這會導致各個 reducer 內幾乎沒什麼東西,沒什麼 business logic ,只有一個 setter function 把新 state 給記錄下來而已。

reducer 內不該這麼空洞吧?

但若是把這些 business logic 移出 component,等於是降低 component 的重用性?


如果在檔案結構上,小元件與能操作它的小 reducer 可以放在一起 ... cohesion 等於超級高?近乎獨立模組?

但 redux 就變成此模組的 dependency 了,或許也不太好。

小元件依靠 props 與外部互動絕對是件好事,非常 functional programming,預測性高,無副作用。

但在設計上來說,只靠 value 跟 onChange 是對的嗎?value 吃進 state,onChange 通知外部更新後的 state?

更新資料的商業邏輯,放在哪裡比較好呢?

  • 小元件
  • parent component
  • reducer

(待研究)


退一步講,在前端開發的領域裡面,什麼是 business logic?


Separation of concerns,如果 React component 只處理 props -> html,以及 trigger event -> notify model,這兩件事,會單純許多?

model 要拿收到的 input 去怎麼更新 state 則是另一回事 ... 剛好交給 redux 負責?


至於model 要拿收到的 input 去怎麼更新 state,如果寫在 component 內,等於是純 React 的寫法 ... 比較肥大,但是整個 component 可以直接重用?

寫在 redux 內,就要用 component + reducer 作為呈現&操作的搭配,還是可以重用。


或許這種建資料目的的面板頁面,幾乎就是由多個表單所組成,所以各表單邏輯留在區塊內即可,稱不上是 app level 的 business logic。

真正 app level 的 business logic 自然會放不進區塊元件內,reducer 會是明顯好去處。

  分享   共 2,000 次點閱
按了喜歡:
共有 0 則留言
還沒有人留言。歡迎分享您的觀點、或是疑問。
您的留言
尤川豪
445 貼文  ·  275 留言

Devs.tw 是讓工程師寫筆記、網誌的平台。隨手紀錄、寫作,方便日後搜尋!

歡迎您一起加入寫作與分享的行列!

查看所有文章