一、react应用(基于react脚手架)

脚手架:用来帮助程序员快速创建一个基于xxx库的模板项目。
(1)包含了所有需要的配置(语法检查、jsx编译、devServer)
(2)下载好了所有相关的依赖
(3)可以直接运行一个简单的效果
react提供了一个用于创建react项目的脚手架库:create-react-app。
项目整体技术架构为react+webpack+es6+eslint。
使用脚手架开发的项目的特点:模块化、组件化、工程化。
react脚手架有webpack。
在这里插入图片描述
创建的模板项目内容:
在这里插入图片描述
在这里插入图片描述
上图中提示了:修改App.js文件并保存后页面会自动重新加载。
在这里插入图片描述
注意:使用react写项目时只有一个index.html文件(一个页面),其他都为组件。
在这里插入图片描述
在这里插入图片描述
说明
(1)可以看到,index.js将APP组件绑定到index.html中的id="root"的div节点。
(2)<React.StrictMode></React.StrictMode>用来检查APP中有问题的地方。
在这里插入图片描述
注意:.js文件和jsx文件在import时可以省去后缀(.js和.jsx),其他文件后缀不能省略
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

组件的组合使用-TodoList案例

模块化和初始化

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
先来思考可以把页面拆分成几个组件。可以是输入框一个组件Header,下面的list一个组件List,list中的每一项是一个组件Item,最后的一行(全选、全不选)一个组件Footer。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
有一个问题,Header组件的输入需要传递给List的组件,但是组件之间传递数据还没有讲述,只讲述了父组件向子组件传递数据,所以存储数据的state需要放到父组件App中(称为“状态提升”)。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现添加

要实现输入框的内容传递到App的state的数据中,需要Header子组件给 App父组件传递数据,方法是父组件通过props给子组件传递一个函数,在函数中对数据进行处理。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
父组件可以获取到子组件的数据,接下来实现添加功能。
在这里插入图片描述

yarn  add nanoid #下载生成唯一id(uuid)的库

在这里插入图片描述
可以实现输入后添加效果。

鼠标移入

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

对props进行限制

接下来进行App组件对Header和List组件传递props进行类型及必要性的限制。
下载依赖:

yarn add prop-types

在这里插入图片描述
在这里插入图片描述

删除功能

也是父组件App传递给子组件List一个删除方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

全选功能

在这里插入图片描述
在这里插入图片描述
使用数组的reduce()方法对数据进行条件统计。reduce方法是对数组进行遍历,第一个参数是一个方法,方法的第一个参数pre是上一次遍历的返回值(第一次遍历是reduce的第二个参数0),方法第二个参数todo是当前遍历数组元素,每次遍历改变返回值。这个reduce方法是计算出数组中元素的done值为true的个数。
接下来实现全选后的底部按钮也被自动勾选的功能:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
但是会报错,因为checked属性被赋值,onChange也需要被赋值。
在这里插入图片描述
上图中,全选按钮选择后需要改变List中的值,所以handleCheckAll()方法还是需要从父组件App传递过来。
在这里插入图片描述
在这里插入图片描述
但是还有一个问题,

在这里插入图片描述
另外,加上全取消功能:
在这里插入图片描述
在这里插入图片描述

总结

在这里插入图片描述

二、react ajax

React本身只关注界面,并不包含发送ajax请求的代码。
前端应用需要通过ajax请求与后台进行交互(json数据)。
react应用中需要集成第三方ajax库或自己封装。

常用的ajax请求库

1.jQuery:比较重,如果需要另外引入不建议使用。
2.axios: 轻量级,建议使用。
(1)axios封装XmlHttpRequest对象的ajax
(2)axios采用promise风格
(3)可以用在浏览器端和node服务器端
下载axios库:

yarn add axios

代理(解决跨域问题)

先来看一个axios发送get请求的案例:
在这里插入图片描述
在这里插入图片描述
修改react项目中的请求地址:
在这里插入图片描述
在这里插入图片描述
注意:上述跨域请求还是达到了后台服务,但是请求的数据回不来。
解决跨域需要通过代理解决。这个代理是一个中介,该服务的端口号也是3000,它可以给5000发请求并且可以返回数据(因为代理发送的不是ajax请求,不会产生跨域问题)。

配置代理方法1

接下来在react项目中配置代理,在package.json文件中配置。
在这里插入图片描述
在这里插入图片描述

配置代理方法2

配置代理方法1中的方式有点问题,只能配置一个代理,即端口号3000下的服务没有的内容都找5000请求。
需要请求一个新的端口号服务的数据:
在这里插入图片描述
配置多个代理需要在src目录下新建一个setupProxy.js文件:
在这里插入图片描述
这个文件不能用ES6语法写,需要用CJS(即common javascript)语法写。react会找到这个文件,加到webpack的配置中,webpack写的都是CJS(内容不用记,知道要配就行)。
在这里插入图片描述
说明:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

github搜索案例

在这里插入图片描述
输入内容后返回搜索到的结果数据:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
静态数据效果:
在这里插入图片描述
注意:List组件中的imag节点中的href值需要是有效的图片地址(可以去百度找一些图片把图片地址粘贴进来)。

补充:JS的解构赋值

解构赋值的一般写法如下:
在这里插入图片描述
在这里插入图片描述
解构赋值的连续写法:
在这里插入图片描述
在这里插入图片描述
解构赋值重命名:
在这里插入图片描述
在这里插入图片描述
继续案例。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上述不会产生跨域问题是因为github服务器后端用cors直接解决了跨域,请求它的服务不会产生跨域。但是github服务请求多次会不响应,需要用其他服务。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
返回中的avatar_url是头像地址,html_url是个人主页地址。
List获取到数据,需要传给search展示,所以数据存放在他们共同的父组件App的state中。
在这里插入图片描述
App传递存储返回users数据的方法给Search。
在这里插入图片描述
Search将返回结果调用App的方法存储到App的state中。
在这里插入图片描述
在这里插入图片描述
给List中的多个元素加key属性,id是请求返回的数据里的字段。
在这里插入图片描述

消息订阅与发布pubsub(兄弟组件之间通信)

实现兄弟组件之间通信的消息订阅和发布需要使用依赖库pubsub。

yarn add pubsub

原理是组件A发布消息并携带数据,组件B若订阅了组件A的消息,则在组件B可以获取到组件A发布的消息和数据。

发布消息:

import PubSub from 'pubsub.js'
PubSub.publish('MY_TOPIC',"hello,world!")

订阅消息:

import PubSub from 'pubsub.js'
var mySubscriber = function(msg,data){
   console.log(msg,data);
};
var token = PubSub.subscribe('MY_TOPIC',mySubscriber)

在这里插入图片描述
对于之前的例子,Search组件需要把数据传给List组件,所以是Search发布消息,List订阅消息。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
继续实现github搜索功能:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:其实消息时间订阅与发布不仅适用于兄弟组件之间,任何组件之间都可以。

fetch发送请求

JS发送ajax请求方式有:
(1)xhr:

const xhr = new XmlHttpRequest();

(2)jQuery:底层是对XmlHttpRequest的封装
(3)axios:底层是对XmlHttpRequest的封装
还有一个内置库,可以不用xhr发送ajax请求,是fetch。
在这里插入图片描述
在这里插入图片描述
注意:这里输出的内容没有返回数据,这是一个粗略的建立和服务器建立连接的请求。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意,不是请求两次,是请求后先进行请求是否成功的判断,再分别进行处理,成功则获取其他数据,失败报错。
在这里插入图片描述
可以对上述写法进行优化:
在这里插入图片描述
用await也可以实现上述功能:
在这里插入图片描述
await只等待成功的结果,失败的结果不管,所以要加上try-catch处理异常情况。
在这里插入图片描述
使用fetch请求实现消息发布和订阅:
在这里插入图片描述
注意:fetch是原生,使用率不高,因为老版本浏览器不兼容(了解即可)。

三、React路由

3.1 SPA

常常需要实现如下效果:
在这里插入图片描述
在这里插入图片描述
以前是使用多个页面的形式,如上面的About栏和Home栏对应的展示区内容是about.html和home.html两个页面。
SPA的模式(SPA即single page web application,单页web应用):
整个应用只有一个页面;点击页面链接不会刷新页面,只做局部更新即改变展示区的组件(使用路由技术);数据都需要通过ajax请求获取,并在前端异步展现。

3.2 路由

路由定义

一个路由就是一个映射关系(key:value),key是路径,value可能是function或component。每一个路径(导航栏中每一项)对应一个组件。

路由分类

路由分为前端路由和后端路由。
在这里插入图片描述
后端路由示例(node.js编写):
在这里插入图片描述
在这里插入图片描述

前端路由原理

前端路由需要靠浏览器的history。

浏览器的history

前端程序员通过BOM操作history。
history.push()是往浏览器的历史记录中存入一条数据。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
a标签绑定onclick方法再进行测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
浏览器的hostory记录是一个栈的结构。
在这里插入图片描述
点击后退按钮就是把栈顶元素出栈跳转到对应页面。
在这里插入图片描述
在上图中在点击浏览器的回退按钮或者点击回退按钮,直接从test3.html回退到test1.html。

history两种工作模式

方式1:直接使用H5推出的history的API

let history = History.createBrowserHistory()

方式2:hash值(锚点)

let history = History.createHashHistory()

在这里插入图片描述
点击push test2按钮跳转:
在这里插入图片描述
看一个例子:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3 路由的基本使用react-router

react-router是react的一个插件,专门用来实现一个SPA应用,基于react的项目基本都会用到此库。专门用于we应用的库是react-router-dom库。

yarn add react-router-dom@5

注:因为react-router-dom更新为版本6,下面的讲述是基于版本5的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在React中靠路由链接Link组件实现切换组件,即导航区使用Link组件,Link组件需要写在BrowserRoute组件内部。
在这里插入图片描述
在这里插入图片描述

Link组件中的属性to的值就是点击该组件的跳转地址。
先来看效果:
在这里插入图片描述
在这里插入图片描述
接下来实现展示区内容:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面的代码能实现功能,但是如果要加内容的话需要把BrowserRouter标签继续往外包。有一个方便的方法,直接把BrowserRouter包在组件App外面:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:
在这里插入图片描述
之前说过,有两种路由器BrowserRouter和HashRouter,将App组件使用HashRouter试试:
在这里插入图片描述
在这里插入图片描述

路由组件VS一般组件

可以看到,在使用路由组件后没有使用:

<Home/>
<About/>

上面的组件是一般组件。
在这里插入图片描述
标准化开发一般把路由组件放在pages目录下。
之前讲述过,一般组件通过props传递数据,没传props是空。
Router组件会默认传递一些数据。
在这里插入图片描述
点击导航栏的About:
在这里插入图片描述

NavLink

要给导航栏选中的模块加高亮效果,需要给标签加active。
在这里插入图片描述
但是不能写死。为了方便,可以使用NavLink标签,它自动实现高亮效果。
在这里插入图片描述
在这里插入图片描述
效果:
在这里插入图片描述
也可以通过NavLink的属性activeClassName(默认值为active)自定义样式:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

封装NavLink

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上图中标签内的内容通过title属性传递。
另外,想进一步优化成如下写法(通过标签体传递内容):

<MyNavLink>Home</MyNavLink>
<MyNavLink>About</MyNavLink>

其实,标签体也是一个标签属性children:
在这里插入图片描述

在这里插入图片描述
所以,封装组件可以优化为:
在这里插入图片描述
其实,上图中的代码等效于下图代码
在这里插入图片描述

3.4 switch使用

现在的效果是,刚进入页面时展示区默认为空:
在这里插入图片描述
只有点击左侧导航栏后才会展示对应内容。
React中若Router组件有多个,路由改变后会遍历所有的Router组件把符合的都展示在展示区,即Router组件的to值可以相同,且一起展示。但这样效率较低,可以使用switch设置找到一个符合条件的Router组件后就不再匹配。
在这里插入图片描述
在这里插入图片描述

3.5 解决样式丢失问题

在这里插入图片描述在这里插入图片描述
但是存在一个问题,刷新页面后样式会丢失:
在这里插入图片描述
先来说一些其他的东西。
项目的public目录时项目的根路径。即http://localhost:3000等同于public目录。
在这里插入图片描述
若是访问的资源在public目录里找不到,则默认返回public中的index.html文件。
在这里插入图片描述

从上图中可以看出bootstrap.css文件的请求地址。
在这里插入图片描述
使用/atguigu/home和/atguigu/about两级目录:
在这里插入图片描述
启动服务首次访问bootstrap.css的请求路径正常:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
找不到也是200,但是返回内容为index.html。
在这里插入图片描述
原因是当有两级目录时,把http://localhost:3000/atguigu当成了public目录。

1.删除./

在这里插入图片描述

2.加%PUBLIC_RUL%

在这里插入图片描述

3.

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.6 路由的模糊匹配和严格匹配

模糊匹配

在这里插入图片描述
在这里插入图片描述
可以看到,NavLink的to属性前缀与Route的path属性相匹配就是匹配成功。
但注意下面的情况:
在这里插入图片描述
在这里插入图片描述
默认是模糊匹配。

精准匹配

在这里插入图片描述
在这里插入图片描述
注意:开启严格匹配可能会引发严重的问题,默认不开启。

3.7 Redirect使用

在这里插入图片描述
用户输入http://localhost:3000访问时,Route组件中没有匹配的,这时可以加一个Redirect组件,找不到匹配的Route组件则按照Redirect设置的路由规则自动跳转页面。
在这里插入图片描述

3.8 嵌套路由(二级路由)

在这里插入图片描述
将Home组件差分,拆分为News组件和Message组件。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
加上外层路由路径后外层路由能够模糊匹配。
在这里插入图片描述
在这里插入图片描述
这里解释下,当点击了News导航栏后,于是路径变成了/home/news,路由的匹配按照注册顺序,先是对App组件内的路由匹配,匹配到/home,Home组件展示。再对Home组件内的路由进行匹配,匹配到/home/news,News组件展示。
所以不能给一级路由开启严格匹配exact,因为有二级路由的情况下,开启了严格匹配的一级路由的所有子路由都失效了。
在这里插入图片描述

3.9 向路由组件传递参数数据

用一个案例说明。
目标效果:
在这里插入图片描述
在这里插入图片描述
可以看出,Message又出现一个导航区和展示区,上面的Message001、Message002、Message003的区域是导航区,下面的文字是展示区。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在遇到一个问题,需要把消息1(Link)的内容传递给下面的文本框Detail,这就是路由传递携带参数的情况
路由组件传递参数的方式有三种。

params参数

先实现一种简单的模式。
在这里插入图片描述
在这里插入图片描述
注意:上面Link组件的的to属性不能用字符串的形式(因为要传变量名),需要`符号(模板字符串,ES6+,可以嵌入变量),再用花括号,表示JS中的
这样的写法传递的参数默认在Detail组件中的props中。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:
在这里插入图片描述

search参数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到search参数没有对参数整理成json对象的形式,可以用一个react脚手架自动下载的库qs实现转换,使用示例如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

state参数

注意:这个state参数是路由组件特有的,不要和组件特定state弄混。
state参数的优点是是路由路径和参数分开写。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:使用state参数传递url中没有携带参数数据,刷新页面也能正常显示,因为BrowserRouter操作浏览器的history,state数据在history中的location中。
在这里插入图片描述
但是如果删除了缓存再刷新就会有问题,解决方法是对空数据的情况进行处理:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
params参数使用较多,其次是search,再其次是state。一般要是传递的参数是私密信息(比如手机号)就要使用state参数。

3.10 push和replace

之前说过路由就是多浏览器的history进行操作(包括push和replace),默认的路由操作是push,也就是每一次进行路由跳转都会留下痕迹。

在这里插入图片描述
刚进入页面默认是localhost:3000/about(重定向),点击Home后localhost:3000/home/news入栈,再点击Message后localhost:3000/home/message入栈,点击“消息1”后localhost:3000/home/message.detail入栈。
点击后退会依次倒退。
那如何开启replace模式呢?
用一个示例说明,点击“消息1”、“消息2”、“消息3”使用replace模式。
在这里插入图片描述
在这里插入图片描述

3.11 编程式路由导航

之前使用的都是Link组件进行路由导航。但是若是要实现一种功能,News组件等待3s后往Meassage组件跳转。
编程式路由导航就是切换路由可以通过代码设定,不一定通过点击触发。
用一个例子说明:
在这里插入图片描述
在这里插入图片描述
push 按钮的实现方法类似:
在这里插入图片描述
在这里插入图片描述
可以看出这个方法携带的是params参数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
state参数形式:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
另外,还可以使用goBack(),goForward方法实现回退、前进功能。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
history还有一个方法是go(),go(1)表示前进一步,go(2)表示前进两步;go(-1)表示后退一步,go(-2)表示后退两步。
在这里插入图片描述
在这里插入图片描述

3.12 withRouter的使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
报错的原因是Header的使用是一般组件,没有this.props.history。
在这里插入图片描述
想让一般组件也使用路由组件的history,需要使用插件withRouter。
withRouter可以把一般组件加上路由组件的API。
在这里插入图片描述

3.13 BrowserRouter和HashRouter区别

在这里插入图片描述

四、React UI组件库

接下来学习一些UI组件的使用,帮忙绘制页面。

antd

antd是ant-design(国内蚂蚁金服)创作的插件。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
安装antd组件:

yarn add antd

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
还有其他的UI 组件库,比如Elment-UI、vant-UI(针对移动端设计给vue用)。

五、redux

redux是一个专门用于做状态管理的JS库(不是react插件库),它可以用在react、angular、vue等项目中,但基本与react配合使用,作用是集中式管理react应用中多个组件共享的状态
在这里插入图片描述
现在有一个需求是组件D的数据{a:1,b:2},组件A、B、C、E、F都要使用,之前说过可以把数据给App的state,通过赋值箭头方法给组件属性的方式,还有消息订阅与发布的形式,因为通信较多这样写起来很麻烦,若是使用redux就会变得简单。

redux是独立所有组件存在的,D将数据交给redux,其他组件去redux中获取数据。
在这里插入图片描述
在这里插入图片描述

5.1 redux原理图和3个核心概念

在这里插入图片描述
通过一个案例来说明redux原理图,例子要实现的效果为,左上角的数字为当前值,下拉框选择一个数据,右边再选择一个运算符,计算后左上角数据变为(当前值)(运算符)(下拉框选择的数字),例如,左上角当前值为0,下拉框选择1,选择+,则左上角数字变为1(0+1=1).
在这里插入图片描述
在这里插入图片描述
ReactComponents为组件,对于0+1=1操作,组件把+1的操作告诉ActionCreators,ActionCreator把动作对象action(包括type和data)分发给Store(相当于调度者,负责全局的掌控,不存储加工数据,只分发),Store把数据(previousState旧数据、action动作,如上例中previousState=0,action=+1)交给Reducers处理完后返回newState给Store,ReactComponents通过getState()从Store获取newState。另外,Reducers也可以初始化状态,传递的previousState为undefined,action包含初始化动作类型和数据。
注意:上图中store只有一个,其他元素可以有多个。
对于初学者,Action Creator可以不用,自己创建。

5.2 redux案例

纯react版

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

简化版redux

先只有Store和Reducers,不用ActionCreators.
安装redux

yarn add redux

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
组件使用store和reducer:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
可以看到还没有调用reducer就初始化了,即执行了countReducer(),是store自行调用的。
在这里插入图片描述
注意:redux中reducer数据变化不会自动引起页面数据的更新。需要再调用render()。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
代码简化:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
注意:redux只负责管理状态,至于状态的改变驱动着页面的展示,需要程序员自己写。

完整版redux

完整版相对与简化版多了ActionCreator,会新增两个文件。
一个文件是ActionCreator相关。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在实际开发中,ActionCreator的type的枚举值不会直接写在ActionCreator中,新建一个常量模块管理。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

异步action

方法返回值为对象Object的action是同步action,返回值为函数的action是异步action。
之前异步加的实现:
在这里插入图片描述
可以在组件里写等待执行,直接使用redux的异步action。
在这里插入图片描述
在这里插入图片描述
但是上面的代码会报错,因为store不允许actioncreator返回函数。
在这里插入图片描述
解决该问题需要先下载一个中间件:

yarn add redux-thunk

在这里插入图片描述在这里插入图片描述
还有一个需要完善的地方。
在这里插入图片描述
注意:异步action中一般会调用同步action。
在这里插入图片描述

5.3 reactc-redux

注意:之前redux是另一个团队做的,后来facebook公司发现在react中使用redux的人很多,就自己做了一个react-redux插件。
在这里插入图片描述
UI组件一般写在component目录,容器组件写在container目录。
下载:

yarn add react-redux

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
原因是找不到store。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们可以看到Count容器组件和UI组件Count的父子关系不是显示写的(在connect()())中,不能通过属性赋值(props)把数据传给子组件。
可以在connect()()第一个()传递两个参数(参数需要是方法),第一个函数参数的返回值作为状态传递给UI组件,第二个函数参数的返回值是操作状态的方法(上面react-redux模型图的第4点)

在这里插入图片描述
在这里插入图片描述
容器组件Count的store是从App组件传递过来的:
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
接下来实现计算功能:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
继续实现减法和奇数加法:
在这里插入图片描述
在这里插入图片描述
继续实现异步加方法:
在这里插入图片描述
在这里插入图片描述

简写mapDispatch

在这里插入图片描述
在这里插入图片描述
虽然简写方式没有添加dispatch进行分发,但是react-redux会执行分发。

provider组件的使用

另外,connect()()中具有了监测redux中状态改变的能力,可以不用自己加监测。
在这里插入图片描述
在这里插入图片描述
使用Provider给App组件中所有的容器组件加上store。
在这里插入图片描述

整合UI组件和容器组件

在这里插入图片描述

多个Reducer

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

redux的reducer函数是纯函数

在这里插入图片描述
在这里插入图片描述

更多推荐