作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
编者注:本文由我们的编辑团队于2022年10月17日更新. It has been modified to use embedded code demos, 参考最近的数据, and align with our current editorial standards.
企业级React应用程序的开发人员知道状态管理对于一致的最终用户体验是多么重要.
然而,用户并不是唯一受状态管理影响的人. 开发人员反应 创建和维护状态. 他们希望状态管理简单、可扩展和原子化. React has moved in this direction by 引入钩子.
当状态应该在许多组件之间共享时,可能会出现问题. 工程师必须找到适合他们需要的工具和库, 同时满足企业级应用程序所需的高标准.
在本文中, 我分析和比较了最流行的库,并选择了最适合的一个 反应状态管理 in an enterprise-level application.
React具有跨多个组件提供数据的优秀工具. 的主要目标 Context 是为了避免螺旋桨钻井. 我们的目标是获得一个易于使用的工具来管理企业应用程序中可能遇到的各种场景中的状态:频繁的更新, 重新设计, the introduction of new features, 等等.......
Context的唯一优点是它不依赖于第三方库, 但这并不能抵消维持这种方法所付出的努力.
While all this is theoretically doable with Context, 它需要一个定制的解决方案,需要时间来设置, support, 和优化. Context的唯一优点是它不依赖于第三方库, 但这并不能抵消维持这种方法所付出的努力.
作为React团队成员 Sebastian Markbage提到过, 上下文API不是为高频更新而构建和优化的,而是为低频更新而构建和优化的,比如主题更新和身份验证管理.
有 dozens of state management tools on GitHub (e.g., Redux, MobX, Akita, Recoil, and Zustand). 然而,考虑到每一个因素都会导致无休止的研究和比较. 这就是为什么我把选择范围缩小到三个主要竞争对手的原因 受欢迎程度, usage, and 维护人员.
为了更明确地进行比较,我使用了以下质量属性:
Redux is a state container created in 2015. It became wildly popular because:
你有 一个全球性的商店 您的数据存放在哪里. Whenever you need to update the store, you dispatch 一个动作 这就是 减速机的. 根据操作类型的不同,reducer会以不可变的方式更新状态.
要在React中使用Redux,您需要通过React - Redux将组件订阅到存储更新.
切片是Redux代码库的基本部分,它区别于其他工具. Slices contain all the logic of actions and 异径接头.
/ /片/计数器.js
import { createSlice } from "@reduxjs/toolkit";
export const slice = createSlice({
名称:“计数器”,
initialState: {
值:0
},
还原剂:{
increment: (state) => {
state.Value += 1;
},
decrement: (state) => {
state.Value -= 1;
}
}
});
导出const actions = slice.行动;
导出const reducer = slice.减速机;
/ /存储.js
import { configureStore } from "@reduxjs/toolkit";
import { reducer as counterReducer } from "./片/计数器”;
导出默认配置恢复({
减速机:{
柜台:counterReducer
}
});
/ /索引.js
从“React”中导入React
从“react-dom”中导入ReactDOM
import { Provider } from 'react-redux'
导入应用程序./App'
从'导入存储'./store'
ReactDOM.render(
,
文档.getElementById(根)
)
// App.js
从“React”导入React;
import { useSelector, useDispatch } from "react-redux";
导入{actions}./片/计数器”;
const App = () => {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
回报(
{count}
);
};
导出默认App;
MobX 是另一个相对较老的库,在GitHub上有~25,800颗星. 它与Redux的不同之处在于它遵循OOP范式并使用可观察对象. MobX是由 米歇尔Weststrate 它目前由一群开源爱好者在波士顿的帮助下维护 Mendix.
In MobX, 在构造函数中创建一个带有makeObservable调用的JavaScript类 可观察到的商店 (如果你有合适的加载器,你可以使用@observable装饰器). Then you declare properties (state) and methods (actions and 计算的值)的班级. 组件订阅这个可观察存储来访问状态, 计算值, 和行动.
Another essential feature of MobX is 可变性. 它允许在您想要避免副作用的情况下静默地更新状态.
MobX的一个独特之处在于,您可以创建几乎纯ES6类,其中隐藏了所有的魔力. 它需要较少的特定于库的代码,以便将注意力集中在逻辑上.
/ /存储/计数器.js
import { makeAutoObservable } from "mobx";
类CounterStore {
值= 0;
构造函数(){
makeAutoObservable(这个);
}
增加(){
this.Value += 1;
}
减量(){
this.Value -= 1;
}
}
导出默认的CounterStore;
/ /索引.js
从“React”导入React;
import ReactDOM from "react-dom";
import { Provider } from "mobx-react";
导入App./App";
从“./商店/计数器”;
ReactDOM.render(
,
文档.getElementById(“根”)
);
// App.js
从“React”导入React;
import { inject, observer } from "mobx-react";
const App = inject((stores) => ({ counter: stores.柜台}))(
observer(({ counter }) => {
回报(
{counter.value}
);
})
);
导出默认App;
Recoil 是React团队的最新产物. 它背后的基本思想是missing的一个简单实现 反应特性 like shared state and derived data.
您可能想知道为什么要为企业级项目审查实验性库. Recoil得到了Facebook的支持,并被用于Facebook的一些应用程序中, 并在React中带来了一种全新的共享状态的方法. 我敢肯定,即使Recoil被弃用,另一个工具也会遵循同样的路径,比如 Jotai,将获得关注。.
Recoil is built on top of two terms: atom and 选择器. 原子是一个共享状态块. A component can subscribe to an atom to get/set its value.
如图所示,当值发生变化时,只会重新呈现订阅的组件. 它使后坐力非常高效.
Another great thing Recoil has out of the box is the 选择器. 选择器是从原子或其他选择器聚合的值. 对于消费者来说, 原子和选择器之间没有区别——它们只需要订阅一些反应部分并使用它.
当一个原子/选择器被改变时,使用它的选择器(例如.e., are subscribed to it) are reevaluated.
Recoil的代码与其竞争对手有很大的不同. 它基于React钩子,更关注状态结构,而不是改变状态.
/ /原子/计数器.js
从"recoil"中导入{atom};
const counterAtom = atom({
关键:“计数器”,
默认值:0
});
导出默认的counterAtom;
/ /索引.js
从“React”导入React;
import ReactDOM from "react-dom";
import { RecoilRoot } from "recoil";
导入App./App";
ReactDOM.render(
,
文档.getElementById(“根”)
);
// App.js
从“React”导入React;
import { useRecoilState } from "recoil";
import counterAtom./原子/计数器”;
const App = () => {
const [count, setCount] = useRecoilState(counterAtom);
回报(
{count}
);
};
导出默认App;
当涉及到企业级应用程序时,这些React全局状态管理库提供了不同的优缺点.
Recoil还很年轻,但目前还没有社区和生态系统. 尽管Facebook正在开发它,而且它的API看起来很有前景, 一个庞大的React应用不能依赖于一个社区支持薄弱的库. In addition, it’s experimental, making it even more unsafe. 对于今天的React企业应用来说,这绝对不是一个好的选择,但值得关注.
MobX和Redux没有这些问题,市场上的大多数大公司都在使用它们. 让他们彼此不同的是他们各自的学习曲线. MobX要求对响应式编程有基本的了解. 如果参与项目的工程师不够熟练, the application may end up with code inconsistencies, 性能问题, 增加了开发时间. 如果您的团队意识到反应性,MobX是可以接受的,并且将满足您的需求.
Redux也有一些问题,主要是关于可伸缩性和性能. 然而,与MobX不同的是,这些问题都有经过验证的解决方案.
Taking every advantage and disadvantage into account, and considering my personal experience, 我推荐Redux作为React企业级应用程序的最佳选择.
Yes, state management is necessary in React. In fact, 使用适当的状态管理库是至关重要的,因为React状态的任何变化都会立即显示给用户
React的useState是本地状态管理的最佳选择. If you need a global state solution, 最流行的是Redux, MobX, 以及内置的Context API. 您的选择将取决于您的项目的规模、您的需求和您的工程师的专业知识.
Maintaining global state is easy if you keep it clean. 它应该只包含那些在多个松散连接的组件之间共享的项.
Context API’s functionality is tiny out of the box. 它不是为高频更新而构建和优化的,而是为主题更新和认证管理等低频更新而构建和优化的.
No, Redux doesn’t need a lot of boilerplate. With the introduction of the official Redux Toolkit, describing state management in Redux has become concise.
MobX is global state management implemented with RxJS. If you want to become an ace, learn RxJS. 它不仅有助于理解单个库, but also for the whole concept of reactivity.
Recoil performs well, even in its experimental stage. It’s not ideal for a large application, 但对于一个不太依赖政府的小银行来说,这将是有用的.
World-class articles, delivered weekly.
World-class articles, delivered weekly.