Part3-Redux与React Redux
预习视频
视频P38-P55
今日学习目标
1、掌握redux概念与使用
2、掌握react-redux的使用
一、何时用Redux?【了解】
首先明确一点,Redux 是一个有用的架构,但不是非用不可。事实上,大多数情况,你可以不用它,只用 React 就够了。
曾经有人说过这样一句话:
"如果你不知道是否需要 Redux,那就是不需要它。"Redux 的创造者 Dan Abramov 又补充了一句:
"只有遇到 React 实在解决不了的问题,你才需要 Redux 。"简单说,如果你的UI层非常简单,没有很多互动,Redux 就是不必要的,用了反而增加复杂性。
从项目角度看,如果你出现了以下情况,就可以考虑使用Redux:
* 用户的使用方式复杂
* 不同身份的用户有不同的使用方式(比如普通用户和管理员)
* 多个用户之间可以协作
* 与服务器大量交互,或者使用了WebSocket
* View要从多个来源获取数据从组件角度看,如果你的应用有以下场景,可以考虑使用 Redux:
发生上面情况时,如果不使用 Redux 或者其他状态管理工具,不按照一定规律处理状态的读写,代码很快就会变成一团乱麻。你需要一种机制,可以在同一个地方查询状态、改变状态、传播状态的变化。
总之,不要把 Redux 当作万灵丹,如果你的应用没那么复杂,就没必要用它。另一方面,Redux 只是 Web 架构的一种解决方案,也可以选择其他方案。
二、Redux设计思想【了解】
Redux 的设计思想很简单,请记住这两句话:
Redux三大原则:
唯一数据源
保持只读状态
数据改变只能通过纯函数来执行
三、流程图剖析【了解】
来看看Redux流程图(Redux Flow):
四、案例与API结合【重要】
我们来完成一个TodoList:
1、创建项目+安装redux与antd
2、页面基本结构
src目录下,只保留:index.js 与 TodoList.js 两个文件,其余全部删掉。
index.js 中:
TodoList.js 中:
效果如图:
3、Store与Reducer
src目录下创建store文件夹,作为仓库使用。在其中新建 index.js 与 reducer.js ,分别写:
store/index.js 中:
reducer.js 中:
这里做个补充:
state: 指的是原始仓库里的状态。
action: 指的是action新传递的状态。
以上代码中,将原本写在 TodoList.js 文件中的数据,拿到reducer中,此时 TodoList.js 中就会缺少数据,这时候,我们对它进行修改:
TodoList.js 中:
以上代码中,为了简洁,做了很多省略,目的是方便大家看到核心代码。
4、安装Redux DevTools
通常我们会希望在浏览器中调试Redux状态值,因此,将这个程序包直接拽入Chrome的扩展程序:
就是这个压缩包(注意:不要解压,直接拽入即可!!!):
安装好插件后,关闭当前项目页面,再重新打开页面,然后打开控制台,能看到这个界面,就算安装成功:
最后,在 store/index.js 中添加这句:
添加后的 store/index.js 整体为:
五、事件驱动【重要】
1、Input的输入事件
当input输入时,我们需要修改输入框的值,于是:
TodoList.js 中:
当然,我们要修改的是store中的值,但唯一能触发store修改值的,是通过Action,因此,我们需要在输入事件中,创建一个action对象:
此时,由于store只是一个仓库,它会自动将action转发给reducer。我们可以在reducer中打印一下:
结果如下:
如此,我们成功了。但我们只是打印了出来,我们真正要修改的是输入框可以看到的文字,于是:
我们先判断
type是不是正确的,如果正确,我们需要从新声明一个变量newState。(记住:Reducer里只能接收state,不能改变state。),所以我们声明了一个新变量,然后再次用return返回回去。
来看看代码实现:
此时,来看看效果:
可以看到,我在修改输入框的值,控制台显示的状态是改变了,但输入框的文字没变。因为我们没有订阅 。
2、订阅
使用订阅可以解决以上问题:
TodoList.js 中:
现在我们搞定了!
But!
这样做说实话不太方便,于是从4.0.5版本开始,非受控组件也可以不用写订阅了。
既然是非受控组件,那么input身上就不能绑定value值。所以,删掉input标签的value属性,以及刚写的订阅,也可以实现。但这就不能给input提供初始值,只能将初始值挂靠在placeholder身上。所以这里不太建议大家删掉这个value和订阅。
3、按钮点击事件(增加列表项)
TodoList.js 中:
reducer.js 中:
4、双击删除列表项
接下来,我们实现一个功能:
通过双击列表项,删除该列表项
TodoList.js 中:
reducer.js 中:
此时,我们实现了双击删除的功能,但我们的reducer有很多if判断,所以我们可以酌情改为 switch...case,这完全看你个人心情。
reducer.js 的改写:
5、课堂练习
使用Redux完成累加功能
Add.js:
store.js:
reducer.js:
六、ActionTypes【熟悉】
实际开发中,我们会写很多个action,其中的type就会出现很多个,因为每个action中必带一个type,这样就导致我们要找一个bug会比较难,而且不可复用。所以我们将action的type抽离出来,成为 actionTypes.js 文件:
然后在 reducer.js 和 TodoList.js 两个文件中引入并修改:
reducer.js 中:
TodoList.js 中:
当然,这还是不够简洁,毕竟有很多重复性的action堆在每个页面中,所以我们需要创建一个 store/actionCreator.js ,专门用来写action。
七、ActionCreator【熟悉】
store/actionCreator.js 中:
将原本所有定义action的代码都搬到这份文件,然后在 TodoList.js 中引入这份文件:
八、Redux总结
我们来对Redux进行一个总结:
其中,我们解释第三点:
很多新手会在reducer每个判断中,去增加Axios请求,但类似于请求这个东西,返回出来的结果都是由后台工程师决定的,你也不知道返回出来的结果是不是函数,所以请大家不要在这些判断中写任何请求、获取时间戳等事件。
九、Redux-thunk中间件【了解】
Redux-thunk 是Redux最常用的插件。什么时候会用到这个插件呢?比如在Dispatch一个Action之后,到达reducer之前,进行一些额外的操作,就需要用到middleware(中间件)。在实际工作中你可以使用中间件来进行日志记录、创建崩溃报告,调用异步接口或者路由。 这个中间件可以使用是Redux-thunk来进行增强(当然你也可以使用其它的),它就是对Redux中dispatch的加强。
首先 thunk 来源自 think 的”过去式“ -- 作者非常特别的幽默感。主要意思就是声明一个函数来代替表达式,这样就可以将执行求值操作(evaluation)延迟到所需要的时刻。
1、安装插件
2、配置
这里注意,按照官方文档的配置,是没法成功的,这里提供正确的配置方法。
store/index.js 中,做如下修改:
3、使用方法
以往我们在页面中的异步行为(数据请求或定时器),可以迁移到 actionCreator.js 中:
页面中:
这里其实有个比较麻烦的点,我还得先套一个promise,这样代码比较多。如果我可以将这个setTimeout也转移到actionCreator中,那么代码就比较少了。
actionCreator.js 中:
页面中:
除了redux-thunk之外,还有redux-saga等中间件。
十、Redux-saga中间件(扩展)
github地址:https://github.com/axelav/redux-saga
saga 是英语 传奇 的意思。它的思想是 拦截。redux-saga 是 redux 一个中间件,用于解决异步问题。redux-saga基于ES6的Generator,大家可以先预习:Generator与function*。
Saga的 redux-saga/effects 中有几个关键字:
fork:创建一个新的进程或者线程,并发发送请求。
call:发送 api 请求
put:发送对应的 dispatch,触发对应的 action
takeEvery:监听对应的 action,每一次 dispatch 都会触发
takeLatest:监听对应的 action,只会触发最后一次 dispatch
all:跟 fork 一样,同时并发多个 action,没有顺序。
由于redux-thunk与redux-saga两者作用大致相同,但redux-saga需要基于generator,写起来也较为复杂,这里只做个概念普及,有兴趣的同学可以自行查阅文档学习。
十一、React-Redux是什么?【了解】
React-Redux 这是一个React生态中常用组件,它可以简化 Redux 流程,其实就是简化版的 Redux。
十二、安装与引入【熟悉】
1、安装
2、引入并使用redux
我们新建一个项目,保留 App.js 、 index.js 、store/index.js 和 store/reducer.js,我们通过React-redux来实现累加。
App.js 中:
index.js 中:
store/index.js 中:
store/reducer.js 中:
十三、提供器与连接器【重要】
1、Provider提供器
<Provider> 是一个提供器,只要使用了这个组件,组件里边的其它所有组件都可以使用 store 了,这也是React-redux的核心组件了。
我们可以对 index.js 进行如下修改:
以上代码中,凡是放在 <Provider> 中的组件,都可以获取到store中的数据。
2、connect连接器
我们已经可以获取到数据,但需要在组件中设置连接器。
接下来,我们需要到 App.js 中进行修改:
以上主要删除了store的引入,增加了连接器与映射关系。
3、事件派发
接下来我们需要点击按钮增加count,其实就是修改store中的count。
App.js 中:
reducer.js 中:
如此,我们就成功实现了对count的累加。
十四、ReactRedux流程图【了解】
十五、课堂练习【重要】
使用React-redux完成TodoList。
代码:
src/index.js:
src/TodoList.js:
store/index.js:
store/reducer.js:
十六、作业
使用 React-Redux 完成 TodoList。
最后更新于
这有帮助吗?









