Redux
- 什么时redux
- redux是一个专门用于状态管理的JS库(不是react插件库)
- 它可以用在react、angular、vue等项目中,但基本与react配合使用
- 作用:集中式管理react应用中多个组件共享的状态
- 什么情况下需要使用redux
- 某个组件的小黄太需要让其他组件可以随时拿到(共享)
- 一个组件要改变另外一个组件的状态(通信)
- 总体原则:能不用就不用,如果不用比较吃力才考虑使用
redux工作流程
- React Components:getState()从Store中获得新状态
- action:动作对象,包括动作类型type(字符串,唯一)和动作数据data(任意类型,可选属性),Object类型的对象
- dispatch(action):分发action,将action对象继续送下去
- Store:调度者,负责全局掌控,dispatch将action交给store
- Reducers:初始化或加工状态,并将新状态返回给Store。初始化时传递的previousState是undefined。加工时根据旧的state和action,产生新的state纯函数
精简使用redux
- 去除自身需要共享的状态
- src下建立
- -src
- –redux
- —store.js
- —xxx_reducer.js
- store.js
- 引入redux中的createSore函数,创建一个store
- createStore调用时要传入一个为其服务的reducer
- 记得暴露store对象
- xxx_reducer.js
- reducer的本质是一个函数,接收:preState、action,返回加工后的状态
- reducer有两个作用:初始化状态,加工状态
- reducer被第一次调用时,时store自动触发的,传递的preState时undefined,传递的action是:{type:‘@@REDUX/INIT_a.2.b.4’}a.2.b.4为随机字符
- 在index.js中检测store中状态的改变,一旦发生改变,重新渲染
【备注】redux只负责管理状态,至于状态的改变驱动着页面的显示,需要我们自己写。
完整使用
相比于精简使用,新增两个文件
- xxx_action.js:专门用于创建action对象
- constant.js:防止容易写错的type值
异步action
aciton可以为对象,也可以为函数
- Object类型的一般对象action叫做同步action
- 函数类型的action叫做异步action
异步action:
不是必须要用的
//异步action就是指action的值为函数
//异步action中一般都会调用同步action
export const createAsynAction = (data,time) => {
return () => {
setTimeout((dispatch)=>{
//通知redux执行任务
dispatch(createAction)//createAction为创建action对象
},time)
}
}
- 明确:延迟的动作不想交给组件自身,向交给action完成
- 想要对状态进行操作,但是具体的数据靠异步任务返回(非必须)
- 具体编码:异步action需要中间件
- yarn add redux-thunk,并配置在store中
- 创建action的函数不再返回一般对象,而是一个函数,该函数中写异步任务
- 异步任务有结果后,分发一个同步的action去真正操作数据
【备注】异步action不是不许要写的,完全可以自己等待异步任务的结果之后再去分发同步action
react-redux
- 所有的组件都应该包裹一个容器组件,他们是父子关系
- 容器组件负责和redux通信,里面可以随意的使用redux 的api
- UI组件中不能使用任何redux的API
- 容器组件会传给UI组件:redux中所保存的状态,用于操作状态的方法
- 容器给UI传递状态、操作状态的方法,均通过props传递
创建一个容器组件——靠react-redux的connect函数
connect(mapStateToProps,mapDispatchToProps)(UI组件)
mapStateToProps:映射状态,返回值是一个对象
mapDispatchToProps:映射操作状态的方法,返回值是一个对象
【备注】容器组件中的store时靠props传进去的,而不是在容器组件中直接引入
mapDispatchToProps可以简写成一个对象,key是方法名,value是action对象。redux会自动为action对象dispatch。
优化:
- 容器组件和UI组件整合一个文件
- 无需自己给容器组件传递store,给包裹一个即可
- 使用了react-redux后也不用再自己检测redux中状态的改变了,容器组件可以自动完成这个工作
- mapDispatchToProps也可以简单的写成一个对象
- 一个组件要和redux“打交道”要经过
-
- 定义号UI组件——不暴露
-
- 引入connect生成一个容器组件并暴露。:connect(state=>({key:value}),{key:xxxAction})(UI组件)
-
- 再UI组件中通过this.props.xxxx读取状态、操作状态
-