Part3-Redux与React Redux

预习视频

【最新】零基础快速入门React 17.x

视频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.jsTodoList.js 两个文件,其余全部删掉。

index.js 中:

TodoList.js 中:

效果如图:

3、Store与Reducer

src目录下创建store文件夹,作为仓库使用。在其中新建 index.jsreducer.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.jsTodoList.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的加强。

preview

首先 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.jsindex.jsstore/index.jsstore/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。

最后更新于

这有帮助吗?