react中数据状态管理的四种方案
我们为什么需要状态管理?
(1) 一个是为了解决相邻组件的通信问题。
虽然可以通过「状态提升」解决,但有两个问题:
每次子组件更新,都会触发负责下发状态的父组件的整体更新(使用 Context 也有这个问题),然后写一大堆 PureComponent、shouldComponentUpdate,代码还能看吗?React 设计中的糟粕写了个够,太惨。
逻辑比较多的话,都写在父组件里,代码还能看吗?根本不考虑父组件的感受。
所以「状态提升」不是个好思路,还是需要状态管理。
(2) 另外,状态管理最重要的一个好处,就是 ——
它可以把「与服务器交互」和「操作数据」的逻辑,从组件中提取出去,组件只用接收处理好的数据即可。这就相当于分离了个 Service 层出去,很好的开发模式。
代码逻辑分离,各司其职,组件去干组件该干的事,这才是最大的好处。
所以我们需要状态管理。
react中数据状态管理的四种方案:
- 1、redux
- 2、mobx
- 3、dva
- 4、hook
一、redux
redux-thunk
使用redux-thunk,在Dispatch一个Action之后,到达reducer之前,可以使用中间件来进行日志记录、创建崩溃报告,调用异步接口等。
以前actionCreators.js都是定义好的action,这些action都是对象,根本没办法写业务逻辑, 有了Redux-thunk之后,可以把TodoList.js中的componentDidMount业务逻辑放到这里来编写。 也就是把向后台请求数据的代码放到actionCreators.js文件里。 (以前的action是对象,现在的action可以是函数了,这就是redux-thunk带来的好处)
redux-thunk和tag-v6:redux-saga的使用感受: 区别主要在于对副作用的管理上
- (1)redux-thunk使得原本只能是对象的action可以是函数,用来处理一些异步请求的操作,actonCreators.js中既有对象的action,也有函数的action。
- (2)redux-saga可以使用saga中间件运行创建的saga.js文件,将actionCreators.js中函数形式的action(处理异步请求)放到来saga.js文件中,这样看来actionCreators.js中就全部是对象的action,saga.js中根据action的类型专门用来处理业务逻辑,再结合saga使用来ES6的Generator功能,让异步的流程更易于读取,写入和测试,结构也更加清晰
- (3)在不引入中间件时,请求的逻辑处理直接放在了组件中,在请求函数中调用了数据更新action的动作。
react-redux库的作用
无论是
redux-thunk
还是redux-saga
和redux
结合使用,在组件中要想使用store中的数据,都需要引入这个store,并对这个数据仓库进行数据监听store.subscribe(this.storeChange)
。React-Redux这是一个React生态中常用组件,它可以简化Redux流程,通过和以上中间件的使用对比,react-redux组件带来的变化主要是改变了组件使用store的方式、获取store中state的方式、获取action的方式,这里不和redux-thunk以及redux-saga的使用冲突,相对而言,更是一种补充。
mobx
mobx实际开发中没有用过,不过通过官方文档中todolist的demo,对mobx的工作机制有所了解。
- mobx可以使用
observable
定义一些需要被观察的状态 - 组件视图的观察可以引用
mobx-react
的observer
,import {observer} from 'mobx-react';
- 当通过
action
或者computed
改变被观察的数据后,组件中所引入这些数据的地方也会随着改变。 - 一般可以使用类组件和装饰器来简化代码,提高开发效率。
- 至于其他的mobx的一些用法,目前还没了解过。
dva
dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch。
当有行为动作改变数据的时候,可以通过 dispatch 发起一个 action,如果是同步行为会直接通过 Reducers 改变 State ,如果是异步行为(副作用)会先触发 Effects 然后流向 Reducers 最终改变 State,所以在 dva 中,数据流向非常清晰简明
- dva主要是以Model的形式来管理数据的状态,每个Model都有自己用的一个命名空间
namespace
。 - 其中定义需要维护的数据
state
, 以及同步处理的reducer
,和用于异步处理的effect
。 - 整个应该的
state
由多个小的Model
合成,在Model
外触发action
,可以使用namespace
指定使用哪个命名空间中的reducer
进行数据处理。 - 数据和组件的绑定也是通过
connect
根据命名空间namespace
进行的绑定。
app.model({namespace: 'todo',state: [],reducers: {add(state, { payload: todo }) {// 保存数据到 statereturn [...state, todo];},},effects: {*save({ payload: todo }, { put, call }) {// 调用 saveTodoToServer,成功后触发 `add` action 保存到 stateyield call(saveTodoToServer, todo);yield put({ type: 'add', payload: todo });},},subscriptions: {setup({ history, dispatch }) {// 监听 history 变化,当进入 `/` 时触发 `load` actionreturn history.listen(({ pathname }) => {if (pathname === '/') {dispatch({ type: 'load' });}});},},
});
(1)Model 对象的属性
namespace
: 当前 Model 的名称。整个应用的 State,由多个小的 Model 的 State 以 namespace 为 key 合成state
: 该 Model 当前的状态。数据保存在这里,直接决定了视图层的输出reducers
: Action 处理器,处理同步动作,用来算出最新的 State。可以看做是 state 的计算器。它的作用是根据 Action,从上一个 State 算出当前 State。effects
:Action 处理器,处理异步动作。基于 Redux-saga 实现。Effect 指的是副作用。用于处理异步操作和业务逻辑,不直接修改 state。会先触发 Effects 然后流向 Reducers 最终改变 State。
(2)call 和 put:dva 提供的effect 函数内部的处理函数。
call
:执行异步函数put
:发出一个 Action,类似于 dispatchseclect
: 在effects中对于param数据和当前的state数据进行再出处理,用于获取当前state。
react中数据状态管理的四种方案相关推荐
- React中的状态管理---Mobx
Mobx的介绍 Mobx是一个功能强大,上手非常容易的状态管理工具.redux的作者也曾经向大家推荐过它,在不少情况下可以使用Mobx来替代掉redux. Mobx流程图 Mobx使用流程 创建项目 ...
- react怎么存上一页_如何实现 React 中的状态自动保存?
什么是状态保存? 假设有下述场景: 移动端中,用户访问了一个列表页,上拉浏览列表页的过程中,随着滚动高度逐渐增加,数据也将采用触底分页加载的形式逐步增加,列表页浏览到某个位置,用户看到了感兴趣的项目, ...
- [react] 描述下在react中无状态组件和有状态组件的区别是什么?
[react] 描述下在react中无状态组件和有状态组件的区别是什么? 1,无状态组件主要用来定义模板,接收来自父组件props传递过来的数据,使用{props.xxx}的表达式把props塞到模板 ...
- taro更新页面数据_Taro 全局数据状态管理
我们一说到全局数据状态管理时,对于 Vue 框架,或许你想到的是 Vuex:对于 React 框架,或者你想到的是 Redux:在微信小程序中,globalData 内定义全局使用变量:而在 Taro ...
- 深入解析react关于事件绑定this的四种方式
这篇文章主要介绍了详解react关于事件绑定this的四种方式,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. 在react组件中,每个方法的上下 ...
- python可以实现哪些功能_Python中实现机器学习功能的四种方法介绍
本篇文章给大家带来的内容是关于Python中实现机器学习功能的四种方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在本文中,我们将介绍从数据集中选择要素的不同方法; 并使用S ...
- java将一个整数按字节输出_在java中的整数类型有四种,分别是 byte short int long 其中byte只有一个字节 0或1,在此不详细讲解。其他的三种类型如下:1、...
在java中的整数类型有四种,分别是 byte short int long 其中byte只有一个字节 0或1,在此不详细讲解. 其他的三种类型如下: 1. 基本类型:short 二进制位数:16 ...
- c语言中字符串去掉逗号,JS四种方法去除字符串最后的逗号
window.οnlοad=function() { var obj = {name: "xxx", age: 30, sex: "female"};//定义一 ...
- java indexof 子字符串_Java中字符串中子串的查找共有四种方法(indexof())
Java中字符串中子串的查找共有四种方法(indexof()) Java中字符串中子串的查找共有四种方法,如下: 1.int indexOf(String str) :返回第一次出现的指定子字符串在此 ...
最新文章
- 《算法基础》——2.3 求幂运算
- 基于 OSGi 的面向服务的组件编程
- Android中TimePicker时间选择器的使用和获取选择的时和分
- boost::graph模块使用 read_graphviz 加载 GraphViz Dot 文本的示例 ,图转换为具有自定义属性的 BGL adjacency_list 图
- 性能优化--布局优化技巧
- Oracle-13:Oracle中的表分区
- RabbitMQ六种队列模式-工作队列模式
- 【xargs使用】查询包含某字符串的所有文件
- tensor backward_Pytorch中的backward函数
- Linux学习总结(18)——Linux使用init命令关机、重启、切换模式
- HDU 3949 XOR (线性基第k小)题解
- 【优化算法】人工鱼群优化算法(AFSA)【含Matlab源码 1078期】
- 你画我猜 计算机题目,你比我猜游戏爆笑词语(你画我猜题目大全500道)
- 互联网企业实习面试经验分享(谷歌微软hulu阿里腾讯字节美团百度等等)
- 产品思维训练 | 卖菜的店同时也卖水果,卖水果的店为什么不卖菜?
- 解决pip Could not fetch URL There was a problem confirming the ssl certificate: HTTPSConnectionPool问题
- 跨境电商APP解决方案
- 用java计算小数的双阶乘
- java与es8实战之五:SpringBoot应用中操作es8(带安全检查:https、账号密码、API Key)
- Google地图的Street View和Mapplets