React 為什麼能撐住大型前端:我看見的是「組合」帶來的可維護性
React 真正撐住大型專案的,不是某個 API,而是「用組合管理複雜度」的架構思路:把結構與變化拆開,讓需求變動變成換積木,而不是拆引擎。
React 為什麼能撐住大型前端:我看見的是「組合」帶來的可維護性
我以前也把 React 當成「把 UI 拆成元件」的工具而已。真正讓我改觀的,是當專案開始變大:人變多、功能變多、需求變動變快,你會發現 React 的強項不是某個 API,而是一整套「用組合管理複雜度」的思考方式。
它把 UI 的複雜度,拆成兩種你可以分開處理的東西:
- 結構(畫面怎麼長)用元件組合描述
- 變化(狀態怎麼變)用資料流與狀態管理描述
這種拆法在小專案看不出差異,但在大型專案,會直接影響你能不能活下來。
1) React 的核心其實是:用「可預測」換「可演進」
React 一開始就把重點放在「宣告式 UI」:你描述在某個 state 下畫面應該長什麼樣,React 去負責把它更新到正確狀態。這件事看似理所當然,但它帶來的架構好處是:
- 當畫面出 bug,你追的是 state 與 props 的來源,不是 DOM 怎麼被手動改壞
- 當需求改了,你改的是「描述」而不是「操作流程」
這會讓大型專案更像在維護一個「狀態機的投影」,而不是一堆互相踩腳的事件處理器。
2) 元件組合(composition)是可維護性的真正槓桿
我最常在 code review 看到的分歧是:有人想做「通用大元件」,有人想做「一堆小元件」。React 的路線其實很明確:你要把可重用性建立在組合上,而不是繼承或魔法參數上。
在大型架構裡,我會用三種組合方式來穩定專案:
A. 容器 / 展示分離(不是教條,是為了讓變動有邊界)
- 容器元件:負責資料取得、狀態組裝、domain 決策
- 展示元件:盡量純 props、可預測、可測試
好處是:資料來源換掉、快取策略換掉、API 形狀調整,都不會一路污染到 UI 細節。
B. 用 children / slots 承接需求變化
需求最愛改的是「這裡多一段、那裡少一段、這個流程多一步」。與其一直加 boolean props,我更偏好把可變的區塊交給組合:
- PageLayout 給 slots:header, sidebar, footer
- Wizard 給 steps:步驟是陣列或子元件組合
- DataTable 給 render props:欄位與 cell 渲染可替換
這種架構很像積木:需求變動時你換積木,不是去改積木裡面的齒輪。
C. 狀態往上提不是口號,是一致性策略
當一個 state 影響多個區塊,就把它提升到共同祖先;當它只影響局部,就留在局部。這看起來很基本,但它其實是在做一件事:把一致性成本集中管理。
3) Server / Client 的邊界,會變成大型前端的分水嶺
React 的下一個大型架構方向,我認為不是「又多一個 hook」,而是讓你更清楚地切割:哪些東西應該留在 client,哪些東西其實更適合在 server 先完成。
React Server Components(RSC)的價值在我眼裡很務實:它讓你可以把「拿資料、組 UI」這件事更靠近資料層完成,並把不需要互動的部分不用送到瀏覽器。你用 "use client" 把互動留在客戶端,其它可以留在 server。
但我也會提醒:這不只是效能議題,也是依賴治理議題。當架構開始吃到更多 server-side runtime 與打包鏈,升級策略會變成架構的一部分。
4) React Compiler:把手工效能微調降級成例外狀況
在大型專案最浪費時間的效能問題,常常不是「真的慢」,而是「大家害怕它會慢」,於是到處塞 useMemo / memo / useCallback,最後變成可讀性下降、bug 變多、而且效益不一定存在。
React Compiler 的方向我很喜歡:它把一部分「自動 memoization」交給工具,讓團隊回到更健康的默認值:先寫清楚,再針對真正瓶頸處理。
5) 我會怎麼用 React 的思路落地「大型前端架構」
如果你正在做一個會長大的產品,我會用這幾條把 React 的優勢變成工程策略:
- 先定義「頁面層」跟「領域層」的邊界:UI 可以常改,但 domain 規則要穩
- 元件設計優先讓組合自然:能用 slots / children 解的,不用魔法 props
- 狀態管理不要一把梭:局部 state 就留局部;跨區一致性才集中
- 導入新能力時,把升級策略當成架構需求(尤其是 server/client split)
- 效能優化以規範先行:先守住不製造問題,再針對瓶頸優化
React 不是保證你永遠不痛,但它提供了一個很好的預設:讓你的程式碼在變大之後,仍然可以用「拆分、組合、替換」來演進,而不是用「硬改、硬撐、硬救火」來維持。
References
- React GitHub Repo:https://github.com/facebook/react