React/ReactNative 状态管理终于懂了!redux redux-toolkit 与 rematch 对比总结
有同学反馈开发 ReactNative 应用时状态管理不是很明白,这个问题我之前刚接触 React 时也遇到过,看了好多文章和视频才终于明白,不得不说,React 及三方库这方面做的有点过于复杂了!
在前面的几篇文章里我们知道了 redux redux-toolkit 和 rematch 如何使用:
- # React/ReactNative 状态管理: redux 如何使用
- # React/ReactNative 状态管理: redux-toolkit 如何使用
- # React/ReactNative 状态管理: rematch 如何使用
这篇文章里,我们来站在更高的角度对比总结一下。
本文主要内容:
- 什么是状态管理
- 有哪些方案,优缺点和使用场景
- Redux React-Redux Redux-Toolkit 和 Rematch 的区别
什么是状态管理
状态(State),就是影响 UI 布局、随着用户操作而变化的变量,比如 checkbox 的勾选状态。
状态管理,就是提供状态的这些操作:
初始化状态
- initState
获取状态
- useSelector
根据状态展示 UI
根据操作更新状态
- dispatch + action
Android 中如何管理状态?
根据 SP/MMKV 或者服务端数据 初始化状态
用户点击后,根据当前状态和操作,更新状态
- state + action = new state
状态变更后,通过 listener 或者 LiveData 通知监听者刷新
React 中提供的状态管理方式略微多一些,根据状态的使用范围,分别有这些 API:
redux 简介及案例
https://github.com/reduxjs/redux
Predictable state container for JavaScript apps
redux 官方介绍,它是一个可预测的状态容器:
- 可预测(可追溯) -> 将状态变更收拢到一起,方便查看变化、排查问题
- 状态容器:保存着全局状态 -> store
核心的三个元素:
- Store: 一个全局的对象(可以理解为一个 JSON )
- Action: 更新指令,通过 type 指定行为
- Reducer: 状态更新函数,参数是当前状态和 action,返回一个新 state
数据流转如下图所示:
界面展示中常常有这样的疑问:“到底是哪里把状态修改了”,比如哪里暂停了播放。
使用 redux,在界面展示异常的时候,只需要去 reducer 中特定的 action 中加日志,看是哪里调用的、参数是什么。
这样做的代价是:限定了修改、获取状态的实现方式,变得繁琐。
有人可能会说了,直接把状态保存到一个全局的 state 对象不是就可以了吗,为什么要用 redux 这么复杂!
global.state = {}
这种方式虽然看着简单,带来的结果是:状态的修改变得无法追踪,类似的逻辑要分散到具体的组件里,不利于维护。
不过在Redux 中,它其实也是维护一个全局对象,只不过提供了标准的更新规范。
上图中的 middleware,可以用作日志、调试等
核心三元素
store
Store 就是一个 JavaScript 对象,全局唯一 -> “单一数据源”
{selected: true
}
action
action 表示要执行的状态修改行为和参数,是一个 JavaScript 对象:
{type: 'ADD_TODO', text: 'xxx'
}{type: 'CHANGE_TODO', text: 'yyy'
}
“type” 是固定的,后面的参数名称可自定义,一般约定为 payload
const action = {type: 'ADD_TODO',payload: 'Learn Redux'
};
reducer
reducer 是状态变化处理函数,它接收 action 并修改全局状态树(修改状态)。
const reducer = (state, action ) => newState
要求是“纯函数”:
- 不修改参数
- 相同的参数,得到结果总是相同的
每个业务有一个自己的 reducer,一个应用里会有 N 个 reducer:
function filterReducer(state = 'SHOW_ALL', action) {if (action.type === 'SET_VISIBILITY_FILTER') {return action.filter} else {return state}
}function todoReducer(state = [], action) {switch (action.type) {case 'ADD_TODO':return state.concat([{ text: action.text, completed: false }])case 'TOGGLE_TODO':return state.map((todo, index) =>action.index === index? { text: todo.text, completed: !todo.completed }: todo)default:return state}
}//全局状态管理函数
function todoApp(state = {}, action) {return {todosState: todoReducer(state.todos, action),filterState: filterReducer(state.visibilityFilter, action)}
}
example
- 状态管理例子从 0 开始: redux
- https://github.com/reduxjs/redux-fundamentals-example-app
redux-toolkit 简介及案例
https://github.com/reduxjs/redux-toolkit
https://redux-toolkit-cn.netlify.app/introduction/quick-start
"@reduxjs/toolkit": "^1.4.0",
redux 官方推荐通过 toolkit 使用 redux,以减少模板代码:
Redux Toolkit 的本质是提供了一些工具函数,简化纯手写 Redux 代码的冗余逻辑,其中最重要的两个工具函数是:
configureStore:管理所有全局状态的函数,它的返回值是一个 Store 对象;
createSlice:管理分片全局状态的函数,其返回值是一个分片对象,该对象上最重要的两个属性是:
actions:创建分片 action 的函数集合
- action 名一般为 slice 名 + action key
reducer:已经创建好的分片 reducer
核心点
redux-toolkit 是怎么简化代码的呢?
和 redux 相比,toolkit 主要在两方面减少了代码:
分发行为时不再需要 action creator
- 不需要单独的 xxxAction 文件
接收数据时不需要 connect
在 redux 中,每次要修改状态时,需要先通过 action creator 创建一个 action,然后分发给对应的 reducer 和 connect;而在 redux-toolkit 中,通过 createSlice 创建 slice 后,可以直接导出它的 actions,这样 UI 组件就省去了创建 action 的步骤。
example
- 状态管理例子从 0 开始:redux-toolkit
- https://github.com/reduxjs/redux-essentials-example-app/tree/tutorial-steps
rematch 简介及案例
"@rematch/core": "^2.0.1","@rematch/immer": "^2.1.3",
rematch 是第三方是基于 redux 开发,封装了一些 API,用于简化代码。
它和 redux-toolkit 非常相似,它的 model 基本上可以等同于 redux-toolkit 的 slice:
不同点在于,rematch 支持多个 store。并且
example
- 状态管理例子从 0 开始:rematch
react-redux
https://github.com/reduxjs/react-redux
"react-redux": "^7.2.4",
这个库主要为 React/React Native 应用提供了 1 个组件和 2 个常用的钩子函数:
Provider:Provider 是一个组件,该组件接收存储所有全局状态的 Store 对象作为参数
- Provider 组件底层用的是 useContext,它为整个应用的其他组件提供获取 Store 对象的能力;
useSelector:从 Store 中获取某个状态,参数是个函数,返回需要的变量
- store.getState() 获取所有状态,不建议
useDispatch:用于发送指令的钩子函数,其返回值是 dispatch 函数,而 dispatch 函数的入参是 action。
<Provider store={store}><Router nativeInfo={props} /></Provider>
function CounterApp() {//获取状态const counter = useSelector((state) => state.counter.value);const dispatch = useDispatch();const handlePress = () => {//通知修改dispatch(counterSlice.actions.increment(10));};return (<View style={styles.box}><Text>{counter}</Text><Text onPress={handlePress}>+10</Text></View>);
}
总结
Redux、Redux Toolkit、React-Redux 和 Rematch 都是 React 应用程序中的状态管理库,提供集中存储和管理应用程序状态的机制。下面是它们之间的区别:
- Redux 是一种可预测的 JavaScript 状态容器,用于管理应用程序的状态,类似于全局存储,不依赖于 UI 库或框架。它让您能够通过单个存储管理整个应用程序的状态,并使用明确定义的规则来管理状态更新。
- Redux Toolkit 实际上是 Redux 应用的官方套件,它提供了一些有用的工具来帮助简化 Redux 应用程序中的常见任务,例如简化构建 store 的方式、处理异步请求、处理原生的 action 处理方案。Redux Toolkit 最大的优势在于使 Redux 应用程序的代码更加简洁、精简,更容易维护。
- React-Redux 提供了在使用 Redux 的 React 应用中的集成方案。它使用 react-redux 中的 Provider、connect 和 mapState 等工具来实现与 React 的协同工作。
- Rematch 是基于 Redux 构建的框架,提供了更轻量级且易于使用的 Redux 模板和生命周期。它的目标是能够在现代 React 生态系统中提供一种更流畅和易用的体验。
综上所述,Redux 是一种通用的状态管理库,Redux Toolkit 是Redux 应用程序的官方套件,它提供了一些有用的工具来帮助简化应用程序中的常见任务,React-Redux 提供了 Redux 应用程序的 React 集成,Rematch 则是一个基于 Redux 构建的轻量级框架,它提供了简单的解决方案来处理复杂的业务逻辑。开发人员应根据其项目的特定要求和约束来选择最适合其需求的方案。
参考资料
- https://time.geekbang.org/column/article/517172
- https://hackernoon.com/redesigning-redux-b2baee8b8a38
React/ReactNative 状态管理终于懂了!redux redux-toolkit 与 rematch 对比总结相关推荐
- React/ReactNative 状态管理: rematch 如何使用
有同学反馈开发 ReactNative 应用时状态管理不是很明白,接下来几篇文章我们来对比下 React 及 ReactNative 状态管理常用的几种框架的使用和优缺点. 上一篇文章介绍了 redu ...
- 【视频】React ReduxToolkit状态管理:创建store对象及redux调试工具的安装方法
React ReduxToolkit状态管理:创建store
- react全局状态管理_rxv: 在React中用Vue3的reactivity包实现状态管理。
前言 React的状态管理是一个缤纷繁杂的大世界,光我知道的就不下数十种,其中有最出名immutable阵营的redux,有mutable阵营的mobx,react-easy-state,在hooks ...
- Recoil 是 React 的状态管理库
Recoil 是 React 的状态管理库,因此你需要将 Recoil 安装到 React 项目中才能使用.创建 React 项目最方便且推荐的方式是使用 Create React App: npx ...
- hooks组件封装 react_名符其实的react下一代状态管理器hox
自从 React16 版本发布 Hooks 以来,大家纷纷上车尝鲜.毫无疑问, Hooks 在一定程度上解决了组件间功能和逻辑复用的问题,在组件间的逻辑的封装和复用确实真香,但 Hooks 在数据状态 ...
- 名符其实的react下一代状态管理器hox
前言 自从React16版本发布Hooks以来,大家纷纷上车尝鲜.毫无疑问,Hooks在一定程度上解决了组件间功能和逻辑复用的问题,在组件间的逻辑的封装和复用确实真香,但Hooks在数据状态的共享方法 ...
- React 全局状态管理的 3 种底层机制
现代前端框架都是基于组件的方式来开发页面.按照逻辑关系把页面划分为不同的组件,分别开发不同的组件,然后把它们一层层组装起来,把根组件传入 ReactDOM.render 或者 vue 的 $mount ...
- react全局状态管理_react 状态管理的复杂度来源
Ui = f(data) 本来按照这个公式,前端开发应该是非常愉悦的.最近发现有一些复杂度是因为现有的工具造成的,导致上面这个公式并不成立. 如果 data 不是一个浏览器的数据,而是数据库里的数据. ...
- react usecontext_Vue3原理实战运用,我用40行代码把他装进了React做状态管理
前言 vue-next是Vue3的源码仓库,Vue3采用lerna做package的划分,而响应式能力@vue/reactivity被划分到了单独的一个package中. 如果我们想把它集成到Reac ...
最新文章
- 介绍一篇通过无监督depth estimation改进语义分割的论文
- c程序设计语言第五单元,(C语言程序设计基础课件)第五单元循环结构程序设计.pptx...
- 如何最小化云API升级造成的中断?
- 如何利用 Arthas 热更新线上代码
- HTML5-canvas实例:刮刮乐游戏
- CSS3中制作倒影box-reflect
- 实现模糊查询并忽略大小写
- Java——线程的创建,线程池
- java 注解入门 简书_Java基础-注解
- 【ElasticSearch】Es 源码之 快照 RepositoriesModule RepositoriesService 源码解读
- WordPress解决上传文件大小限制问题
- 100以内的偶数的个数_10以内数字的奇偶性认识
- 英伟达发布全球最大GPU:性能提升10倍,售价250万
- ant编译mysql驱动
- 谷歌被曝出滥用苹果后门收集用户数据
- c xaml语言教程,Xamarin XAML语言教程基础语法篇大学霸
- SLAM基础——李群李代数
- 记一次重大的生产事故
- 软考 计算机 都有什么考试内容,了解软考是什么 软考考试流程都包括哪些
- [android开发必备]Android开发者社区汇总