企業應用程序的最佳 React 狀態管理工具
已發表: 2022-03-11企業級 React 應用程序的開發人員知道狀態管理對於一致的最終用戶體驗的重要性。
然而,用戶並不是唯一受狀態管理影響的人。 React 開發人員創建和維護狀態。 他們希望狀態管理簡單、可擴展和原子化。 React 通過引入 hooks 已經朝著這個方向發展。
當狀態應該在許多組件之間共享時,可能會出現問題。 工程師必須找到適合他們需求的工具和庫,同時滿足企業級應用程序所需的高標準。
在本文中,我將分析和比較最流行的庫,並選擇最適合企業級應用程序狀態管理的庫。
內置 React 狀態管理功能
React 有一個出色的工具,可以跨多個組件提供數據。 Context 的主要目標是避免螺旋鑽。 我們的目標是獲得一個易於使用的工具來管理企業應用程序中可能遇到的各種場景中的狀態:頻繁更新、重新設計、引入新功能等等。
雖然所有這些在理論上都可以通過 Context 實現,但它需要一個需要時間來設置、支持和優化的自定義解決方案。 Context 的唯一優點是它不依賴第三方庫,但這不能超過維護這種方法的努力。
此外,React 團隊成員 Sebastian Markbage 提到新的 Context API 不是針對高頻更新構建和優化的,而是針對主題更新和身份驗證管理等低頻更新而構建和優化的。
檢查現有庫
GitHub 上有數十種狀態管理工具(例如 Redux、MobX、Akita、Recoil 和 Zusand)。 但是,將它們中的每一個都考慮在內會導致無休止的研究和比較。 這就是為什麼我根據受歡迎程度、使用情況和維護者將我的選擇範圍縮小到三個主要競爭對手。
為了明確比較,我將使用以下質量屬性:
- 可用性
- 可維護性
- 表現
- 可測試性
- 可擴展性(在更大的狀態下具有相同的性能)
- 可修改性
- 可重用性
- 生態系統(有多種輔助工具來擴展功能)
- 社區(有很多用戶,他們的問題在網上得到解答)
- 可移植性(可以與 React 以外的庫/框架一起使用)
還原
Redux 是 2015 年創建的狀態容器。它之所以廣受歡迎,是因為:
- 當它推出時,沒有任何嚴肅的選擇。
- 它提供了狀態和動作之間的分離。
-
react-redux魔術啟用了直接的狀態連接。 - 該庫的共同創建者是著名的 Facebook 開發人員和 React 核心團隊成員 Dan Abramov。
您有一個全球存儲數據所在的位置。 每當您需要更新 store 時,您都會派發一個動作到reducer 。 根據動作類型,reducer 以不可變的方式更新狀態。
要將 Redux 與 React 一起使用,您需要通過react-redux為組件訂閱商店更新。
Redux API 示例
Redux 在代碼庫中區別於其他工具的基本部分是切片。 它們包含所有的 action 和 reducer 邏輯。
代碼沙盒
// slices/counter.js import { createSlice } from "@reduxjs/toolkit"; export const slice = createSlice({ name: "counter", initialState: { value: 0 }, reducers: { increment: (state) => { state.value += 1; }, decrement: (state) => { state.value -= 1; } } }); export const actions = slice.actions; export const reducer = slice.reducer; // store.js import { configureStore } from "@reduxjs/toolkit"; import { reducer as counterReducer } from "./slices/counter"; export default configureStore({ reducer: { counter: counterReducer } }); // index.js import React from 'react' import ReactDOM from 'react-dom' import { Provider } from 'react-redux' import App from './App' import store from './store' ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') ) // App.js import React from "react"; import { useSelector, useDispatch } from "react-redux"; import { actions } from "./slices/counter"; const App = () => { const count = useSelector((state) => state.counter.value); const dispatch = useDispatch(); return ( <div> <div> <button onClick={() => dispatch(actions.increment())}>Increment</button> <span>{count}</span> <button onClick={() => dispatch(actions.decrement())}>Decrement</button> </div> </div> ); }; export default App;質量屬性
- 可用性。 隨著官方工具包的引入,Redux 變得非常簡單。 您創建一個切片(初始狀態、reducers 和操作的組合),將其傳遞給存儲,並通過鉤子在組件中訪問它。
- 可維護性。 Redux 很簡單。 它不需要深厚的知識來理解如何增強或修復某些東西。
- 性能。 Redux 的主要性能影響者是軟件工程師。 Redux 是一個沒有太多邏輯的簡單工具。 如果您發現狀態更新很慢,您可以按照官方指南來加快速度。
- 可測試性。 Redux 由純函數(actions 和 reducers)組成,非常適合單元測試。 它還提供了編寫集成測試的機制,其中 store、action 和 reducer 一起工作。
- 可擴展性。 默認情況下,Redux 有一個全局狀態,因此很難擴展。 但是,有一個 redux-dynamic-modules 庫可以創建模塊化的 reducer 和中間件。
- 可修改性。 自定義 Redux 是一件輕而易舉的事情,因為它支持中間件。
- 可重用性。 Redux 與框架無關,因此它非常擅長可重用性。
- 生態系統。 Redux 提供了一個由有用的附加組件、庫和工具組成的龐大生態系統。
- 社區。 Redux 是我們比較中最古老的狀態管理庫,它已經積累了一個擁有重要知識庫的大型社區。 Stack Overflow 上有約 30,000 個(約 19,000 個已回答)帶有
redux標籤的問題。 - 脈衝。 Redux 會定期更新和維護。
MobX
MobX 是另一個相對較舊的庫,在 GitHub 上有 23,000 顆星。 它與 Redux 的不同之處在於它遵循 OOP 範式並使用 observables。 MobX 由 Michel Weststrate 創建,目前由一群開源愛好者在波士頓 Mendix 的幫助下維護。
在 MobX 中,您可以在構造函數中創建一個帶有makeObservable調用的 JavaScript 類,該構造函數是您的可觀察存儲(如果您有適當的加載器,則可以使用@observable裝飾器)。 然後聲明類的屬性(狀態)和方法(動作和計算值)。 組件訂閱此可觀察存儲以訪問狀態、計算值和操作。
MobX 的另一個基本特性是可變性。 如果您想避免副作用,它允許靜默更新狀態。
MobX API 示例
MobX 的一個獨特功能是您可以創建幾乎純 ES6 的類,所有的魔法都隱藏在引擎蓋下。 它需要較少的特定於庫的代碼來保持對邏輯的關注。
代碼沙盒
// stores/counter.js import { makeAutoObservable } from "mobx"; class CounterStore { value = 0; constructor() { makeAutoObservable(this); } increment() { this.value += 1; } decrement() { this.value -= 1; } } export default CounterStore; // index.js import React from "react"; import ReactDOM from "react-dom"; import { Provider } from "mobx-react"; import App from "./App"; import CounterStore from "./stores/counter"; ReactDOM.render( <Provider counter={new CounterStore()}> <App /> </Provider>, document.getElementById("root") ); // App.js import React from "react"; import { inject, observer } from "mobx-react"; const App = inject((stores) => ({ counter: stores.counter }))( observer(({ counter }) => { return ( <div> <div> <button onClick={() => counter.increment()}>Increment</button> <span>{counter.value}</span> <button onClick={() => counter.decrement()}>Decrement</button> </div> </div> ); }) ); export default App;質量屬性
- 可用性。 可觀察存儲是狀態管理的單一入口點。 它使 MobX 的使用變得簡單,因為您只有修改的地方。
- 可維護性。 這是一個相當大的缺點。 如果不了解 RxJS API,您將無法獲得想要的結果。 在資質不佳的團隊中使用 MobX 可能會導致狀態不一致問題。
- 性能。 MobX 由獨立的商店組成,使您能夠訂閱您需要的唯一商店。 這是非常有效的。
- 可測試性。 Observable 存儲是簡單的 JavaScript 對象,其中隱藏著反應性功能。 測試與任何其他 JavaScript 類相同。
- 可擴展性。 可觀察存儲在邏輯上被拆分; 擴展 MobX 沒有任何困難。
- 可修改性。 MobX 允許創建具有修改行為的自定義 observables。 此外,還有一個概念叫做反應。 反應模型自動副作用。 這些東西讓 MobX 非常可定制。
- 可重用性。 MobX 與框架無關,因此它非常擅長可重用性。
- 生態系統。 MobX 有數百個可用的擴展。
- 社區。 MobX 有很多忠實的粉絲。 Stack Overflow 上有約 1,600 個(約 1,000 個已回答)的帶有
mobx標籤的問題。 - 脈衝。 MobX 會定期更新和維護。
畏縮
Recoil 是一個相對較新的人,是 React 團隊的最新創意。 它背後的基本思想是對缺少的 React 功能(如共享狀態和派生數據)的簡單實現。

您可能想知道為什麼要為企業級項目審查實驗庫。 首先,Recoil 是目前 React 社區中討論最多的話題之一。 其次,Recoil 得到 Facebook 的支持,並且已經在其一些應用程序中使用,這意味著它將在某個時候成為一個穩定的版本。 最後,這是一種在 React 中共享狀態的全新方法,我敢肯定,即使 Recoil 已被棄用,也會有另一個工具遵循相同的路徑。
Recoil 建立在兩個術語之上: atom和selector 。 原子是一個共享狀態片段。 一個組件可以訂閱一個原子來獲取/設置它的值。
正如您在圖像中看到的,當值更改時,只有訂閱的組件會重新渲染。 它使 Recoil 非常高效。
Recoil 開箱即用的另一個很棒的東西是選擇器。 選擇器是從原子或其他選擇器聚合的值。 對於消費者來說,原子和選擇器沒有區別,他們只需要訂閱一些反應部分並使用它。
每當一個原子/選擇器改變時,使用它的選擇器(即訂閱它)都會被重新評估。
反沖 API 示例
Recoil 的代碼與它的競爭對手相比有很大的不同。 它基於 React 鉤子,並且更多地關注狀態結構而不是改變這種狀態。
代碼沙盒
// atoms/counter.js import { atom } from "recoil"; const counterAtom = atom({ key: "counter", default: 0 }); export default counterAtom; // index.js import React from "react"; import ReactDOM from "react-dom"; import { RecoilRoot } from "recoil"; import App from "./App"; ReactDOM.render( <RecoilRoot> <App /> </RecoilRoot>, document.getElementById("root") ); // App.js import React from "react"; import { useRecoilState } from "recoil"; import counterAtom from "./atoms/counter"; const App = () => { const [count, setCount] = useRecoilState(counterAtom); return ( <div> <div> <button onClick={() => setCount(count + 1)}>Increment</button> <span>{count}</span> <button onClick={() => setCount(count - 1)}>Decrement</button> </div> </div> ); }; export default App;質量屬性
- 可用性。 Recoil 是最容易使用的工具之一,因為它的工作方式類似於 React 中的
useState。 - 可維護性。 在 Recoil 中你所要做的就是在組件內部維護選擇器和鉤子——更多的價值,更少的樣板。
- 性能。 Recoil 在 React 之外構建了一個狀態樹。 狀態樹使您能夠獲取和收聽您需要的東西,而不是整個樹的變化。 它在引擎蓋下也得到了很好的優化。
- 可測試性。 Recoil 提供了一種測試其原子和選擇器的機制。
- 可擴展性。 分裂成多個獨立部分的狀態使其成為可擴展性的良好參與者。
- 可修改性。 Recoil 只負責存儲值及其聚合。 它沒有數據流,因此可以輕鬆定制。
- 可重用性。 Recoil 依賴於 React。 它不能在其他地方重複使用。
- 生態系統。 Recoil 目前沒有生態系統。
- 社區。 Recoil 太新鮮了,無法擁有一個大社區。 Stack Overflow 上有大約 70 個帶有
recoiljs標籤的問題。 - 脈衝。 Recoil 不經常更新(最近兩次更新之間間隔了六個月)。 它在 GitHub 上也有很多未解決的問題。
選擇正確的 React 狀態管理工具
當涉及到企業級應用程序時,這些 React 全局狀態管理庫如何疊加?
Recoil 很年輕很新鮮,但目前沒有社區和生態系統。 儘管 Facebook 正在開發它並且 API 看起來很有希望,但一個龐大的 React 應用程序不能依賴於社區支持薄弱的庫。 此外,它是實驗性的,使其更加不安全。 對於當今的 React 企業應用程序來說,這絕對不是一個好的選擇,但值得關注。
MobX 和 Redux 不存在任何這些問題,市場上的大多數大玩家都在使用它們。 使它們彼此不同的是學習曲線。 MobX 需要對響應式編程有基本的了解。 如果參與項目的工程師不夠熟練,應用程序最終可能會出現代碼不一致、性能問題和增加的開發時間。 如果您的團隊意識到反應性,MobX 是可以接受的,並且會滿足您的需求。
Redux 也有一些問題,主要是關於可伸縮性和性能。 然而,與 MobX 不同的是,這些問題有經過驗證的解決方案。
考慮到每一個優點和缺點,並考慮到我的個人經驗,我推薦 Redux 作為 React 企業級應用程序的最佳選擇。
