作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Teimur Gasanov的头像

Teimur Gasanov

Teimur是React的导师,也是Toptal核心团队的高级前端工程师.

专业知识

以前在

Klarna
Share

编者注:本文由我们的编辑团队于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.

Built-in React State Management Capabilities

React具有跨多个组件提供数据的优秀工具. 的主要目标 Context 是为了避免螺旋桨钻井. 我们的目标是获得一个易于使用的工具来管理企业应用程序中可能遇到的各种场景中的状态:频繁的更新, 重新设计, the introduction of new features, 等等.......

Context的唯一优点是它不依赖于第三方库, 但这并不能抵消维持这种方法所付出的努力.

While all this is theoretically doable with Context, 它需要一个定制的解决方案,需要时间来设置, support, 和优化. Context的唯一优点是它不依赖于第三方库, 但这并不能抵消维持这种方法所付出的努力.

作为React团队成员 Sebastian Markbage提到过, 上下文API不是为高频更新而构建和优化的,而是为低频更新而构建和优化的,比如主题更新和身份验证管理.

Examining Existing React State Management Libraries

有 dozens of state management tools on GitHub (e.g., Redux, MobX, Akita, Recoil, and Zustand). 然而,考虑到每一个因素都会导致无休止的研究和比较. 这就是为什么我把选择范围缩小到三个主要竞争对手的原因 受欢迎程度, usage, and 维护人员.

为了更明确地进行比较,我使用了以下质量属性:

  • 可用性
  • 可维护性
  • 表演
  • 可测试性
  • 可伸缩性(在更大的状态下以相同的性能工作)
  • 可修改性
  • 可重用性
  • 生态系统(有各种辅助工具来扩展功能)
  • 社区(有很多用户,他们的问题在网上得到回答)
  • 可移植性(可与React以外的库/框架一起使用)

Redux

Redux is a state container created in 2015. It became wildly popular because:

  • There was no serious alternative when it launched.
  • It provided separation between state 和行动.
  • react-redux magic enabled straightforward state connection.
  • Redux库的共同创建者是著名的Facebook开发者和React核心团队成员Dan Abramov.

动画显示状态和动作的进展,从和到减速器,使用Redux.

你有 一个全球性的商店 您的数据存放在哪里. Whenever you need to update the store, you dispatch 一个动作 这就是 减速机的. 根据操作类型的不同,reducer会以不可变的方式更新状态.

要在React中使用Redux,您需要通过React - Redux将组件订阅到存储更新.

Redux API示例

切片是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;

质量属性

  • 可用性. Redux became very simple with the introduction of 官方工具包包. You create a slice (a combination of the initial state, 异径接头, 和行为), 把它递给商店, and access it in a component via hooks. The addition of RTK Query made Redux Toolkit 更有用 by taking care of standard data querying.
  • 可维护性. Redux很简单. 它不需要深入的知识来理解如何增强或修复某些东西.
  • 表演. The primary performance influencer with Redux is the 软件工程师. Redux is a straightforward tool without much logic. If you see that state updates are slow, you can follow 官方指导方针 让它们更快.
  • 可测试性. Redux由纯函数(操作和reducer)组成,这使得它非常适合单元测试. 它还提供 的机制 编写存储、操作和reducer一起工作的集成测试.
  • 可伸缩性. 默认情况下,Redux只有一个全局状态,这使得它难以扩展. 然而,图书馆 redux-dynamic-modules enables the creation of modular 异径接头 and 中间件.
  • 可修改性. 定制Redux是一件毫不费力的事情,因为它支持 中间件.
  • 可重用性. Redux与框架无关,因此它在可重用性方面非常出色.
  • 生态系统. 回来的了 巨大的生态系统 of helpful add-ons, libraries, and tools.
  • 社区. Redux, the oldest state management library in our comparison, 已经积累了一个拥有重要知识库的大型社区. 带有redux标签的问题有34000个(回答了26000个) 堆栈溢出.
  • Pulse. Redux is still updated and maintained regularly, 但随着项目的成熟,开发速度总体上有所放缓

MobX

MobX 是另一个相对较老的库,在GitHub上有~25,800颗星. 它与Redux的不同之处在于它遵循OOP范式并使用可观察对象. MobX是由 米歇尔Weststrate 它目前由一群开源爱好者在波士顿的帮助下维护 Mendix.

Diagram depicting state management using MobX, 从动作到可观察状态和计算值再到副作用.

In MobX, 在构造函数中创建一个带有makeObservable调用的JavaScript类 可观察到的商店 (如果你有合适的加载器,你可以使用@observable装饰器). Then you declare properties (state) and methods (actions and 计算的值)的班级. 组件订阅这个可观察存储来访问状态, 计算值, 和行动.

Another essential feature of MobX is 可变性. 它允许在您想要避免副作用的情况下静默地更新状态.

MobX API示例

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;

质量属性

  • 可用性. 可观察存储是状态管理的单一入口点. 它使MobX的使用变得简单,因为您只有一个地方可以修改.
  • 可维护性. 这是一个相当大的缺点. 如果不了解RxJS API,您将无法获得期望的结果. 在不合格的团队中使用MobX可能会导致状态不一致的问题.
  • 表演. MobX由独立的商店组成,使您能够订阅您需要的唯一商店. 非常有效.
  • 可测试性. 可观察对象存储是普通的JavaScript对象,其中隐藏了响应功能. Testing is the same as for any other JavaScript class.
  • 可伸缩性. Observable stores are split logically; there is no difficulty in scaling MobX.
  • 可修改性. MobX允许创建带有修改行为的自定义可观察对象. In addition, there is a concept called reactions. Reactions model automatic side effects. These things make MobX very customizable.
  • 可重用性. MobX与框架无关,因此它在可重用性方面非常出色.
  • 生态系统. 有 数百个扩展 适用于MobX.
  • 社区. MobX拥有众多忠实粉丝. 有大约1800个问题(大约1100个回答)带有mobx标签 堆栈溢出.
  • Pulse. MobX定期更新和维护,与Redux一样,已经达到成熟阶段.

Recoil

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.

Diagram depicting state management with Recoil, 展示组件如何订阅原子以检索或设置其值.

如图所示,当值发生变化时,只会重新呈现订阅的组件. 它使后坐力非常高效.

Another great thing Recoil has out of the box is the 选择器. 选择器是从原子或其他选择器聚合的值. 对于消费者来说, 原子和选择器之间没有区别——它们只需要订阅一些反应部分并使用它.

Diagram illustrating the use of 选择器s in Recoil, 它们与原子的关系, and changes caused by different values.

当一个原子/选择器被改变时,使用它的选择器(例如.e., are subscribed to it) are reevaluated.

后坐力API示例

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;

质量属性

  • 可用性. Recoil是最容易使用的工具之一,因为它像React中的useState一样工作.
  • 可维护性. 在Recoil中,您所要做的就是在组件中维护选择器和钩子——更多的价值, 更少的样板.
  • 表演. Recoil builds a state tree outside of React. 状态树使您能够只获取和收听您需要的内容, 不是整棵树的变化. It’s also well-optimized under the hood.
  • 可测试性. 反冲提供 一种机制 for testing its atoms and 选择器s.
  • 可伸缩性. 分裂成多个独立部分的状态使其具有特别的可扩展性.
  • 可修改性. Recoil只负责存储值及其聚合. It has no data flow so it can be customized easily.
  • 可重用性. Recoil依赖于React. 它不能在其他地方重复使用.
  • 生态系统. There is no ecosystem for Recoil at the moment.
  • 社区. Recoil is too fresh to have a big 社区. 有大约200个问题(回答了大约100个)带有recoiljs标签 堆栈溢出.
  • Pulse. Recoil经常更新,与Redux和MobX相比,在GitHub上有最开放的问题.

Which Tool Results in the Best State Management for React?

当涉及到企业级应用程序时,这些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企业级应用程序的最佳选择.

了解基本知识

  • Is state management necessary in React?

    Yes, state management is necessary in React. In fact, 使用适当的状态管理库是至关重要的,因为React状态的任何变化都会立即显示给用户

  • Which state management is best in React?

    React的useState是本地状态管理的最佳选择. If you need a global state solution, 最流行的是Redux, MobX, 以及内置的Context API. 您的选择将取决于您的项目的规模、您的需求和您的工程师的专业知识.

  • How do you maintain global state in React?

    Maintaining global state is easy if you keep it clean. 它应该只包含那些在多个松散连接的组件之间共享的项.

  • 为什么不使用React Context API?

    Context API’s functionality is tiny out of the box. 它不是为高频更新而构建和优化的,而是为主题更新和认证管理等低频更新而构建和优化的.

  • Does Redux require much boilerplate code?

    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.

  • What should I do to become skilled in MobX?

    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生产准备好了吗?

    Recoil performs well, even in its experimental stage. It’s not ideal for a large application, 但对于一个不太依赖政府的小银行来说,这将是有用的.

Hire a Toptal expert on this topic.
现在雇佣
Teimur Gasanov的头像
Teimur Gasanov

位于 Bishkek, Chuy Province, Kyrgyzstan

成员自 2018年5月1日

作者简介

Teimur是React的导师,也是Toptal核心团队的高级前端工程师.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

专业知识

以前在

Klarna

World-class articles, delivered weekly.

Subscription implies consent to our 隐私政策

World-class articles, delivered weekly.

Subscription implies consent to our 隐私政策

Toptal开发者

加入总冠军® 社区.