纯函数
定义
- 确定的输入,一定会产生确定的输出,同样输入的结果,输出一定是一样的。
- 函数在执行过程中,不能产生副作用。
意义
- 放心写,放心用。
- 保证函数纯度,不需要关心传入的内容或者依赖其他外部的变量。
React中要求所有React组件都必须像纯函数一样,保护他们的props不被修改。
- 也就是说子组件不能去修改父组件传过来的值会产生副作用。
redux中的reducer也要求是一个纯函数。
redux
what
- 管理state状态的容器,提供了可预测的状态管理,React只要负责帮助我们管理视图,state如何维护最终由我们确定。
how
-
页面有加减乘除点击了加,告诉Action Creators(行为创造)我要加X,action行为类型为加,内容为X,然后通过dispatch分发到Store仓库中,Store啥也不干把之前的值和行为传给Reducers,Reducers处理完返回新值给Store,最后组件通过getState()获取新值。
-
Redux要求所有数据的变化,必须通过派发(dispatch)action来更新。action是一个普通的js对象,用来描述这次更新的type(行为)和content(内容)。
-
Reducers(纯函数)将state与action联系在一起,它的作用就是将传入的state和action结合起来生成一个新的state(注意是新的 而不是修改之前的state 不能产生副作用),有两种状态,一为初始化状态,二为加工状态。
原则
-
单一数据源,整个应用程序的state应存储在一颗object tree中,并且这颗树只存储在一个store中。
-
state是只读的,唯一修改state的方法是派发action。不需担心竞态问题。
-
使用纯函数来执行修改,将旧state与action联系在一起,并且返回一个新的state。随着应用程序复杂度增加,可以将reducers拆分成多个小的reducers,分别操作不同state tree的一部分。
计时器案例
- 基础版本
- redux精简版本
-
npm i redux -S
-
创建src/redux/store.js src/redux/num_reducer.js
-
store.js
- num_reducer.js
- 修改组件写法
- 更加暴力的重新渲染 修改入口文件index.js
- redux完整版本
- 创建src/redux/constant.js
- 创建src/redux/num_action.js
- 修改num_reducer.js
- 修改组件写法
同步action与异步action
如果action是对象那么称为同步action,如果action是函数那么称为异步action
修改组件写法
运行报错
报错意思是action必须是一个朴实无华的对象,请使用异步action的中间件,也就是请第三方让store意思意思一下执行下函数,最终函数返回派发的还是一个朴实无华的对象再交由reducer处理。
安装中间件 npm i redux-thunk -S 修改store.js
num_action.js的一个优化点
react-redux
背景
react发现大伙喜欢用redux,然而redux不是react官方的,为了使用方便出了react-redux库。
模型图
创建src/containers/Calculator/index.jsx Calculator的容器组件
UI组件已连接到位 准备连接右手redux也就是连接store 引入store 修改App.js
容器组件与UI组件状态和方法的传递与接收 修改src/containers/Calculator/index.jsx
UI组件打印this.props结果
a,b函数重命名 引入action调用dispatch修改状态 修改src/containers/Calculator/index.jsx
修改UI组件
mapDispatchToprops简写优化(不一定是函数可以是对象形式)
无需监测redux中状态的变化 react-redux connect方法已经处理好 修改入口index.js
连接store优化
- 修改App.js
- 修改入口index.js
- 这样一来相当于依赖注入APP下的所有组件想要使用store直接使用。
整合优化 修改src/containers/Calculator/index.jsx
react-redux Hooks
react-redux数据共享示例
定义一个student组件和Calculator组件通过redux进行数据共享 所以需要修改redux文件夹结构
containers下创建Student容器组件
修改App.js 引入student组件
修改containers/Student/index.jsx
修改constant.js
修改redux/actions/student.js
修改redux/reducers/student.js
初步展示结果
引入Student组件的reducer使用
-
可以看到这里只是用了Calculator组件的reducer,那么Student组件的reducer怎么使用?
-
接着看看containers/Calculator/index.jsx redux/reducers/num.js这两个文件
-
这里要说的就是当前的reducers保留的值是Calculator组件的值,如果我们要取到Student组件保留的值,那么reducers的结构是不是就要发生变化了,没错reducers的结构就要变成对象的形式才能有序的获取不同组件保留的值。
-
如何改变结构呢? 你是不是想这样写
- 有点意思,踩坑就对了,正确的做法是合并组件的reducer成对象,然后将这个对象传入。
- 页面会报以下错误 页面不允许放一个对象(此对象是啥不就是更改结构后的reducer对象了吗)
- 所以修改containers/Calculator/index.jsx获取reducer的操作
- 完善containers/Student/index.jsx从reducers中获取student数据
- 页面结果显示
接下来就是Calculator组件和Student组件的数据共享
- 修改containers/Calculator/index.jsx
- 修改containers/Student/index.jsx
- 页面结果显示
新建redux/reducers/index.js用来管理合所有reducer
Redux DevTools扩展辅助工具
浏览器扩展程序下载Redux DevTools
浏览器F12
修改store.js
结果
redux-saga
npm i redux-saga -S
创建redux/saga.js
修改store.js
修改constant.js
修改action.js
修改saga.js
修改组件