上节课我们介绍了如何将容器组件和UI
组件连接起来,这节课我们来介绍一下react-redux
的基本使用。
回顾
在开始这节课的内容之前,我们对上节课的内容做一个简单的回顾
- 容器组件是连接
UI
组件和redux
的桥梁 - 容器组件要接收到
store
,但是必须通过props
传入,不可以手动引入 - 用
react-redux
提供的connect
高阶函数来创建容器组件
以上便是上节课的主要要点,接下来我们来进行这节课的学习。
验证容器组件与UI
组件的父子关系
我们之前得代码中是不是已经引入了UI
组件?而且是不是也已近创建了容器组件?其实store
是不是也已经在了,只不过我们还没有进行连接,那么我们接下来是不是就要让这座桥正式生效来让UI
组件和redux
连接起来了呢?先不忙,我们先来验证一下UI
组件和容器组件的关系。
那么容器组件和UI
组件是什么关系?我们之前在分析原理图的时候,是不是就已经说过了,UI
组件是容器组件的子组件。那么我们来验证一下他们之间的父子关系是不是真的。但是怎么验证呢?
我们来打开控制台,然后切换到开发者工具中,这里是不是很明显就可以看出来这两个是父子关系?
UI
组件展示
那么我们现在也验证了容器组件和UI
组件的父子关系了。那么我们页上展示的数据从哪来?我们之前的案例中是不是直接从redux
的state
里面读出来的?但是现在我们还没有连接redux
,而且UI
组件负责展示,而UI
组件不允许直接去找redux
要数据,那么是不是要通过容器组件?那么容器组件和UI
组件之前的通信是不是直接使用props
就行了?
那么我们怎么从容器组件给UI
组件传东西啊?我们打开了容器组件的代码,我们看不到UI
组件标签的影子啊,那这还传什么props
啊,没学过啊。
那么我们来讲一下,我们创建容器组件是不是要调用connect
?这个函数是高阶函数?我们要柯里化调用。当我们第一次调用connect
函数的时候,要传入两个参数:
- 这两个函数都是函数
- 第一个参数函数的返回值作为状态通过
props
传给了UI
组件 - 第二个参数函数的返回值作为操作状态的方法通过
props
传给UI
组件
那么我们来看一下:
import SumUI from '../../components/Sum'; import { connect } from 'react-redux'; const data = () => ({ a: 100 }); const method = () => ({ b: () => console.log(123) }); export default connect(data, method)(SumUI);
我们来看上面这段代码,什么意思?第一个函数我们是不是返回一个对象?这个函数是不是我们connect
函数第一次调用的时候传递的第一个参数?那么这个函数返回的对象是不是就作为状态通过props
传给了UI
组件。为什么要返回一个对象啊?我们这里是不是通过props
传的?那么通过props
传的话,不是对象我们在UI
组件通过什么key
来取这个值呢?那么为什么说是作为状态呢?因为这个东西是存在redux
中的状态。但是我们现在是不是还没有连接redux
啊,所以说先手写一个出来。
那么第二个函数则是第二个参数,这个函数呢也返回一个对象,这个对象的key
也就作为props
的key
,而value
就是一个函数,这个函数是用来操作状态的方法。那么我们在UI
组件中来打印一下收到的props
吧:
是不是我们传的东西都传进去了,而且,react-redux
还自动传了个store
。我们下不用管这些。那么我们现在是不是能通过这种方法来让我们的UI
组件拿到初始值来做页面的展示了啊?那么我代码就不贴了,大家改一下就行了。
获取state
我们现在已经可以通过容器组件给UI
组件传递数据和方法了,那么我们现在传给UI
组件的数据是不是都是我们写死的?但是我们实际过程中能写死吗?是不是不能啊?那么我们就要从redux
中取啊,怎么取?是不是调用getState
就行了?那么是谁来调用呢?是不是store
来调用getState
方法?那么我们怎么办?
我们之前说了第一个参数函数的返回值作为状态传给UI
组件,那么这个参数函数是谁调用的?是不是react-redux
调用的?而这个函数的作用是什么?是不是就只把数据传进去啊?所以说这个函数在被调用的时候react-redux
就已经自动把state
的值传给函数了。所以说我们直接在这个函数接一下,就可以了,那么我们来看一下:
import SumUI from '../../components/Sum'; import { connect } from 'react-redux'; const data = state => ({ sum: state }); const method = () => ({ cons: () => console.log(123) }); export default connect(data, method)(SumUI);
我们这里稍微显得规范一点,把key
给改了一下。那么这个时候我们的页面是不是就可以拿到我们的值了?那么页面上不就可以正常展示了嘛:
我们来看一下,这次我们直接从redux
中拿到了状态值展示到了页面上。那么这是不是意味着我们已经成功通过容器组件将UI
组件和redux
连接起来了?如果没有连接起来的话,我们还能在UI
组件中拿到redux
中的值吗?但是我们的UI
组件中我们有调用任何跟redux
有关的东西吗?有任何redux
的API
吗?是不是没有?
实现动作
那么我们继续往下看,我们是不是也给UI
组件传了一个方法?我们传的方法是一个打印 123 的函数,那么我们在UI
组件中来用一下试试能不能用。我们把+
按钮的onClick
事件的回调换成了this.props.cons
,那么我们点击一下按钮来看一下效果:
也成功打印了。那么我们是不是就意味着我们把我们所有的动作都通这个方法来实现就行了呢?
// Sum 容器组件 import SumUI from '../../components/Sum'; import { connect } from 'react-redux'; import { createIncrementAction } from '../../redux/sum_action_creator'; const data = state => ({ sum: state }); const method = dispatch => ({ increment: data => dispatch(createIncrementAction(data)) }); export default connect(data, method)(SumUI); // Sum UI组件 export default class Sum extends Component { render() { return ( <div> ... <button onClick={this.add}>+</button> ... </div> ) } add = () => { const { value } = this.selectNum; this.props.increment(value * 1) } ... }
我们来看一下代码,我们直接在我们的容器组件中把传给UI
组件的方法改了一下,这个方法接收一个data
,然后把这个data
直接传给了我们的Action Creator
,但是我们是不是要把行动对象分发下去才能干活啊?是不是就要用store.dispatch
?那么这个store
从哪来?我们第一个函数是专门传state
的,所以第一个函数可以接到state
,那么第二个函数是专门通过动作来操作状态的,状态要由store
分发,那么这个函数是不是就可以接收到store
?其实不是,react-redux
给你封装得更加方便,这里他直接把dispatch
传给你了。
然后再来到UI
组件中,我们的+
按钮的回调中是不是取了我们下拉框选得值,然后再把值传给传进来的这个函数那么是不是就可以实现我们的加法操作了呢?我们来看一下效果:
现在我们就可以实现我们的加操作,那么其他的几个操作是不是就简单了,我们这里就不再赘述了。
总结
以上就是这一小节关于react-redux
的基本使用,但是上面的代码并不规范。
connect
函数在第一次调用时要接收两个参数connect
函数第一次调用时接收到的参数必须都是函数- 第一个函数叫
mapStateToProps
,返回值必须是一个对象,对象的value
是redux
中存的状态值,作为状态通过props
传给UI
组件 - 第二个函数叫
mapDispatchToProps
,返回值必须是对象,对象的value
必须是函数,作为操作状态的方法,通过props
传给UI
组件
Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.
Link of this article:https://work.lynchow.com/article/use_react_redux_basic/