admin 2025-06-30 04:10:45 世界杯2010冠军

React 状态管理库深度对比:在做技术选型的时候如何选择合适的状态库,nolan出品

掘金链接:https://juejin.cn/post/7368288987642232872

1,简介

在状态共享这方面,不像 Vuex,React 的官方并没有强力推荐某种封装方案,所以 React 的状态管理工具五花八门,百花齐放,

react-redux、dva、Context API、mobx、recoil/Jotai、zustand,valtio.

其中就有:

做什么都要 dispatch 的 redux 流派,主打单向数据流,包括:react-redux 、dva、新星代表 zustand

响应式流派 mobx。以及新星代表 valtio ,以及一个很有特点的库 resso

原子状态流派。来自 facebook 开源的 recoil ,以及新星代表 jotai

完全体 hooks 流派。hox、reto、umijs@4 内置数据流,包括 Vue 官方推荐的新状态管理工具 pinia 也是这个流派。

2,为什么会考虑写这篇文章

在公司的项目中使用的是 dva.js 作为 状态管理,但是Dva.js在编写代码时过于臃肿,并且 dva.js 仓库在 2019 年开始就不再维护了,不能及时跟上最新的技术发展。其在 ts 不再都没有任何提示的问题也逐步暴露。更不用说dva.js在错误处理方面极其不优雅,dva.js 在处理错误时,往往会导致整个应用崩溃,而不是只影响出错的部分。这使得我考虑有没有一种更加优雅的方式进行React状态的管理,并且能够完美兼容项目中已有的状态管理方法,作为一种补充手段为开发提效。

并且随着技术不断发展,我们终归是要摆脱繁琐的 dva,寻找一个新的状态管理工具,来减少我们这一块的代码量,对于这块技术的探索就提上了日程

具体改造可以参考我写的这篇文章 https://juejin.cn/post/7321049446443384870?searchId=2024051008370556AFD9AB416FDEE1C534

最终我选择了使用 zustand 作为我们新的状态管理工具引入项目,为什么会选择这个呢,文章的末尾会给我我考虑的理由

3,市面上React状态管理库介绍

在 Web 前端开发中,状态管理是一个非常重要的话题。随着 React 生态圈的不断壮大,越来越多的状态管理工具应运而生。其中主要分为这几个流派:

1. Redux 流派

Redux 是最传统的状态管理库,强调单一数据源、不可变数据和纯函数更新。使用dispatch来触发action,通过reducers处理action并返回新的state。React-Redux提供了与React集成的桥梁。

Redux 的三大原则是:

单一数据源:整个应用的 state 被存储在一个 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。

State 是只读的:唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。

使用纯函数来执行修改:为了描述 action 如何改变 state tree ,你需要编写 reducers。

在 React 生态圈中,有很多基于 Redux 思想的状态管理工具, 例如:

react-redux:

React-Redux 是一个在 React 应用中使用 Redux 的官方绑定库。它提供了一种在 React 组件中连接 Redux store 的方法,使得组件能够获取 store 中的 state 并触发 actions。

简单实用介绍:

npm install react-redux redux //安装依赖

store.js

import {

createStore } from 'redux';

// 定义初始状态

const initialState = {

count: 0 };

// 定义根reducer,它决定了状态如何随着actions而变化

const rootReducer = (state = initialState, action) => {

switch (action.type) {

case 'INCREMENT':

// 当action类型为INCREMENT时,增加count

return {

...state, count: state.count + 1 };

default:

// 默认情况下不改变状态

return state;

}

};

// 使用createStore创建Redux store,并传入根reducer

export const store = createStore(rootReducer);

App.js

import React from 'react';

import {

Provider } from 'react-redux';

import store from './store';

import Counter from './Counter';

// React组件App使用Provider包裹,Provider是react-redux提供的组件,

// 它允许我们将Redux的store传递给组件树的任何部分

function App() {

return (

store}>

);

}

export default App;

Counter.js

import React from 'react';

import {

connect } from 'react-redux';

// mapStateToProps是一个函数,它将Redux store中的状态映射到组件的props

const mapStateToProps = state => ({

count: state.count });

// mapDispatchToProps创建了一个对象,对象中的每个函数当你调用它们时,

// 都会通过dispatch派发一个action,这些函数也会作为props传递给组件

const mapDispatchToProps = dispatch => ({

increment: () => dispatch({

type: 'INCREMENT' }),

});

// Counter是一个普通组件,它接收来自Redux store的count和increment作为props

function Counter({

count, increment }) {

return (

Count: {

count}

{

/* 当按钮被点击时,调用increment prop来dispatch一个INCREMENT action */}

);

}

// 使用connect高阶组件将Counter组件连接到Redux store

// connect函数接受两个参数:mapStateToProps和mapDispatchToProps

// 它返回一个新的组件,这个组件能够访问Redux store中的状态和分派actions

export default connect(mapStateToProps, mapDispatchToProps)(Counter);

这段代码演示了Redux最基础的使用方式:创建store、定义reducer、使用Provider将store提供给组件树、以及使用connect将组件连接到Redux store。通过这种方式,React组件能够获取全局状态并触发状态变更。 特点:

提供了 Provider 组件,用于将 Redux store 传递给 React 组件树。

提供了 connect 高阶组件,用于将 Redux store 中的 state 和 actions 映射到组件的 props。

基于 React 的 context API 实现,避免了不必要的组件重新渲染。

优点:

官方维护,社区支持度高,有很多相关资源。

高性能,避免了不必要的组件重新渲染。

支持中间件,可以方便地扩展 Redux 的功能。

缺点:

学习曲线较陡峭,需要熟悉 Redux 的概念。

代码冗余,需要编写很多样板代码。在大项目的时候简直是灾难,基本不会怎么考虑

需要手动管理 state 更新逻辑。安装依赖:

dva:

受Redux启发,为中国开发者设计,提供简化版的API和模型(model)的概念,集成了Redux、Redux-Saga和React-Redux,使得状态管理更加简洁。

我认为 dva.js 更加适用于中小型的 React 项目,对于大型复杂的项目来说优点难受

首先,使用 npm install dva 安装 dva 依赖。

接下来,创建一个 Dva 应用(app.js):

// 导入 dva 核心库

import dva from 'dva';

// 初始化一个 dva 应用实例

const app = dva();

// 定义一个 model 来管理状态和逻辑,这里是计数器的模型

app.model({

// 命名空间,用于区分不同模块的 action 和 reducer

namespace: 'counter',

// 初始状态

state: 0,

// reducers 负责处理同步操作,更新 state

reducers: {

increment(state) {

// 返回新的 state,这里实现计数器加一的功能

return state + 1;

}

}

});

// 导出 dva 应用实例

export default app;

在应用中使用创建的 Dva 应用(App.js):

// 引入 React 和 dva 的 connect 函数

import React from 'react';

import {

connect } from 'dva';

// 引入初始化的 dva 应用实例

import app from './app';

// 定义 React 组件 Counter,展示计数器状态和提供增加按钮

function Counter({

count, dispatch }) {

return (

Count: {

count}

{

/* 点击按钮触发 action,通过 dispatch 方法 */}

);

}

// 映射 state 到 Counter 组件的 props

const mapStateToProps = state => ({

count: state.counter });

// 使用 connect 函数将 Counter 组件与 Redux store 连接起来

const ConnectedCounter = connect(mapStateToProps)(Counter);

// 配置路由,指定根组件为 ConnectedCounter

app.router(() => );

// 启动 dva 应用,并挂载到页面的 #root 元素上

app.start('#root');

在这个示例中,我们创建了一个简单的计数器应用。首先创建一个名为 counter