React之Redux基础---高级笔录
大纲:
01_认识Redux和文章前言" 02_Redux工作流程讲解" 03_AndDesign和开发环境初始化" 04_用Ant Design制作UI界面" 05_创建Redux中的仓库-store和reducer" 06_Redux_Dev_Tools的安装" 07_通过Input体验Redux的流程" 08_Redux制作ToDoList列表" 09_用Redux实现ToDoList的删除功能" 10_工作中写Redux的小技巧1" 11_工作中写Redux的小技巧2" 12_Redux中常遇的三个小坑" 13_组件UI和业务逻辑的拆分" 14_填坑和Redux中的无状态组件使用" 15_Axios异步获取数据并和Redux结合" 16_Redux-thunk中间件的安装和配置" 17_Redux-thunk的使用方法" 18_Redux-saga的安装和配置" 19_Redux-saga获取TodoList列表" 20_React-Redux的介绍和安装" 21_React-Redux的Provider和Connect" 22_React-Redux修改Store state的值 23_React-Redux增加List数据" 24_React-Redux代码优化"
(1)01_认识Redux和文章前言"
React是一个简单的轻量级试图层框架,只能做视图层的操作。React里的组件通信十分繁琐,比如子组件向父组件通信,改变父组件状态,要通过调用父组件里的方法才能改变。此时便需要配合数据层框架进行数据的状态管理。
(2)02_Redux工作流程讲解
(3)03_AntDesign和开发环境初始化
本节使用AntDesign作为UI框架,是一个面向企业级的框架,由阿里提供开源,视觉和动效做的不错。
刚开始只是针对React做的UI框架,后来逐渐支持Vue、Angular等主流前端框架。官网Ant Design.
接下来开始初始化项目,如果没有全局安装脚手架,那么首先需要安装脚手架
接下来结合脚手架初始化安装项目
接下来编写案例组件ToDoList.jsx并引入
接下来开始安装Ant Design
安装完毕后查看项目说明文档package.json,检查是否安装该依赖
(4)04_用Ant Design制作UI界面
安装完毕后开始利用Ant Design框架优化之前的ToDoList案例,最终效果如下
首先根组件引入样式文件
然后结合核心JS库,对应引入想要使用的组件,比如这里我们要使用input,则引入antd库的Input即可
import {Input} from 'antd'
然后在对应组件里,开始布局
结果如下
接下来添加按钮,这里需要引入按钮组件,如下所示
样式如下
接下来引入List列表组件,定义数组
(5)05_创建Redux中的仓库-store和reducer
首先安装redux
>npm i redux --save
在src下新建仓库文件夹store,所有的状态都在这里进行管理。接着建立仓库管理文件index.js
1、引入createStore方法创建仓库
2、调用方法实例化仓库
3、导出仓库
这里store相当于仓库,我们并不能进行操作,所以这里还需要一个仓库管理员reducers,所以接下来新建仓库管理文件resucer.js。
接下来在仓库管理文件index.js引入reducer.js,然后在实例化仓库注入reducer.
接下来结合之前的ToDoList案例,将之前的数据写入仓库
然后将之前组件里写死的数据去除
此时列表如下所示
然后在组件里引入store/index.js仓库管理文件,然后在构造器里获取仓库数据
接下来将该仓库获取的对象赋值给状态
然后将对象数据赋值到组件
结果如下
(6)06_Redux_Dev_Tools的安装
本节安装个redux调试工具Redux-dev-tools,安装前需要在Chrome配置好FQ(科---学***上+++网),然后在Chrome商店进行下载安装
安装完毕后打开编码控制台查看是否安装成功
点击进行配置
在实例化store时,添加第二个参数即可
const store = createStore( reducer, /* preloadedState, */ + );
參數含义:
window.__REDUX_DEVTOOLS_EXTENSION__表示有Redux-devtools拓展程序插件的情况下,就调用后面的方法window.__REDUX_DEVTOOLS_EXTENSION__()
配置完成后再次刷新页面,控制台如下所示
(7)07_通过Input体验Redux的流程
首先在组件里监听事件
此时已经可以获取输入框输入值
分析流程图可以得知,还缺一个Action,接下来创建action对象,然后通过dispatch传递给store仓库
store相当于仓库,并不具备管理能力,会将接收到的action直接传递给reducers管理者(概念图里的虚线),该过程是自动推送的,接下来由reducers处理业务逻辑。
类似于图书馆store,并不具备管理能力;需要reducers(减压阀)管理人员进行管理
接下来操作reducer.js,首先打印下两个参数
测试如下
此时reducers管理员已经接收到了输入框的变化。接下来是reducers的重点:只读性.
注意:reducer里只能接收state,不能改变state,所以要进行深拷贝
此时修改输入框便会发现redux的修改历史
虽然此时redux里已经发生变化,但是还需要手动更改。接下来还需要进行发布订阅模式.,手动更新state。
接下来在函数里进行改变
如果没有发布订阅,测试如下,首先加入value
测试后发现,如果没有绑定发布订阅,则无法更新state,所以发布订阅不能缺少
注意1:发布订阅函数的bind绑定this操作,必须在订阅操作之前
注意2:手动更改state时必须调用store.getState获取新的state
此时便可以实现redux更新
(8)08_Redux制作ToDoList列表
接下来结合redux完成增加列表功能,即点击添加按钮后,将输入框内容添加至列表
首先完善之前的案例,添加placeholderValue和inputValue,如下所示
开始编写按钮事件
接下来创建action,然后通过dispatch传递给reducer管理员
然后在reducer.js里进行逻辑操作
接下来因为之前已经发布订阅,所以这里不再需要再次发布
此时便已经可以正常添加列表内容
(9)09_用Redux实现ToDoList的删除功能
首先我们结合Ant Design框架给列表项添加删除图标,如下所示(查看Ant Design官网图标组件)
接下来调用组件
结果如下
接下来开始编辑删除操作,如下所示(传入index索引,作为点击时的事件处理依据)
接下来处理点击事件,发送action到reducer.js
最后操作reducer.js即可
因为之前已经做过发布订阅,所以这里便不用再次手动操作。
测试如下:(这里我删除了一个,如下所示redux的调试工具里,state状态也随之更改)
接下来做下完善,结合Ant Design库给添加和删除加个动画效果(Ant Design动画库).
(10)10_工作中写Redux的小技巧1
分析之前的案例,如下所示
当type里少输入一个字母,或者错打单词,如下所示
会发现此时组件无法完成输入,且控制台并没有报错
这显然是不符合业务逻辑的,万一后期出现错误不好查找定位。所以需要添加错误警告提示.
另外,之前的action语法大同小异,这里最好做下代码精简,避免代码冗余
接下来完善以上两个问题
1、抽离action配置
工作里一般会将action的type单独抽离出来放到store/actionTypes.js文件
将之前的action配置项的type抽离绑定到对应大写常项,并导出常量.
接下来在案例组件引入,引入三个常量并依次替换
接下来同理,将reducer.js里的依次替换,同理,先引入,后替换
此时,如果我们在某处编写action的type,不小心再写错单词,此时便会出现报错提示,如下所示
此时,如果项目很大,那么这么处理后便很容易帮助开发者定位错误,此时的复用性也提高了很多。
(11)11_工作中写Redux的小技巧2
还是之前的项目代码,如下所示可以看到组件里的action派发比较多。几乎每一个事件都需要派发一个action
如果项目较为庞大,则会出现导出都是派发的action的情况,不适于管理,也不符合企业开发的规范,所以在开发时,一般将其放置到一个文件actionCreators.js(Creator译为创作者)。
将action作为常量,结合箭头函数,导出为对象格式
接下来在组件里调用使用
然后在对应事件里将其替换
此时便完成了action的提取,同理,将其他两个action也提取出来
此时组件里的action的type常量引入便不再需要,因为都提取到了actionCreators.js文件里。
箭头函数导出对象,详见箭头函数返回对象 && 尾调用优化 .
(12)12_Redux中常遇的三个小坑
1、store唯一性
store必须是唯一的,所有项目下的store都源于src/store/index.js里的createStore。如果存在多个store,则会报错。
2、resucers里逻辑处理state时,state在里面只具备可读性,不能更改。只有state能改变自己的内容
reducer.js里进行store数据深拷贝,然后操作拷贝后的数据,最后返回数据到store/index.js
所以最终还是store/index.js里修改,即只有store才可修改state状态.
3、reducer必须是函数
关于纯函数,详见Redux优化之JS纯函数(Pure Function).和浅谈JS纯函数.
还有一点,这里使用了很多if条件判断,代码较为冗余,可以换成switch...case...语法,参见优雅的在React项目中使用Redux .
(13)13_组件UI和业务逻辑的拆分
目前为止的案例,UI和业务逻辑写在了一个文件里,如下所示
在小公司独立开发时也经常这么些。
但是在大型企业的大型项目开发时,为了提升开发效率一般会将组件的UI视图和业务逻辑进行拆分,交由多人协同开发,在短时间内高效完成产品研发。
接下来将UI组件分离出去,首先新建ToDoListUI.js,然后将render里的部分拆分过去,接着将一些引入文件也引过去,如下所示(这里我简单分离出列表部分做个简单案例ToDoListUI)
注意:***这里将UI组件分离出去后,List.item的循环里无法往回传值,需要在UI组件里多一步操作***
或者直接传值,如下所示(查阅过后总结出,网上大部分文章在这块的写法均是错误的)
原因分析:
之前的写法之所以传不过去index和item,原因在于箭头函数的()里定义局部变量,导致函数体里接受的是新定义的局部变量,
这里我们将()里置空,函数体里直接获取即可
此外,也可以添加咨询框Modal进行优化,详见https://ant.design/components/modal-cn/#components-modal-demo-confirm.
(14)14_填坑和Redux中的无状态组件使用
类似于刚才分离出来的UI组件,里面只有UI的render部分,没有其他业务逻辑,所以可以将其写为无状态组件。
无状态组件本质即为函数/方法,对比之前的Class...extends写法,没有了相关的继承和默认值,性能提高很多
注意:
无状态组件传值,使用props即可,不用this.props
此外,还可以用解构赋值进行适当优化,如下
注意: 1、props传值 2、不再需要Comonent方法,所以只需要引入import React from 'react' 3、有人可能会问,无状态组件主要就是匿名函数,没有react啊,引入干嘛? 原因:底下的JSX语法需要react的支持.
如果我们在无状态组件,没有引入react,则会报以下错误
无状态组件标准:没有业务逻辑,只有UI部分。
特点:因为没有继承Component相关方法特性,所以没有生命周期钩子(本身也就不需要,只有UI渲染)。
(15)15_Axios异步获取数据并和Redux结合
注意:Redux中不能直接使用异步请求获取数据。
1、首先安装axios开发依赖
>npm i axios --save
2、引入使用
然后结合生命周期
因为之前已经配置过跨域,所以这里我们直接用淘宝的API,结果如下
接下来创建action,如下
接着编写action的type
接着操作action,将其注入store
此时已经注入到store,接下来需要在reducers里编写逻辑,间接操作state
1、引入actionType、置空listData数组
2、覆盖置空的数组
此时,如下浏览器所示
(16)16_Redux-thunk中间件的安装和配置
Redux中间件redux-thunk中间件之安装、配置、使用
(17)17_Redux-thunk的使用方法
Redux中间件redux-thunk中间件之安装、配置、使用
(18)18_Redux-saga的安装和配置
Redux中间件redux-saga中间件之安装、配置、使用
(19)19_Redux-saga获取TodoList列表
Redux中间件redux-saga中间件之安装、配置、使用
(20)20_React-Redux的介绍和安装
(21)21_React-Redux的Provider和Connect
React-Redux系列2:Provider和Connect
(22)22_React-Redux修改Store state的值
React-Redux系列3:修改Store state的值
(23)23_React-Redux增加List数据
(24)24_React-Redux代码优化