上节课我们简单介绍了一下react-redux
库,讲到了react-redux
这个库把项目中的组件分为UI
组件和容器组件,那么这节课我们就来介绍一下如何来连接UI
组件和容器组件。
回顾
在开始这节课的学习之前,我们把上节课的内容来简单回顾一下
react-redux
库把组件分为两类UI
组件- 容器组件
- 只有容器组件可以直接操作
redux
UI
组件必须通过容器组件来操作redux
UI
组件所需要的redux
中的状态以及操作状态的方法都要由容器组件通过props
来交互
以上便是上节课的主要内容,接下来我们开始这节课的学习。
UI
组件改写
我们来想一下我们之前的案例中组件都在哪?是不是在components
文件夹中?通常我们在编写react
项目的时候,UI
组件都会放在这里,而容器组件都放在container
文件夹中,那么我们先来把我们的Sum
组件改成一个UI
组件吧。那么,既然是UI
组件的话,我们的组件中是不是就不能有关于redux
的任何东西的存在?
import React, { Component } from 'react' export default class Sum extends Component { render() { return ( <div> <h1>当前求和为:???</h1> <select ref={c => this.selectNum = c}> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <button onClick={this.add}>+</button> <button onClick={this.dec}>-</button> <button onClick={this.odd}>odd</button> <button onClick={this.async}>async</button> </div> ) } add = () => { const { value } = this.selectNum; } dec = () => { const { value } = this.selectNum; } odd = () => { const { value } = this.selectNum; } async = () => { const { value } = this.selectNum; } }
现在我们是不是把所有的redux
相关的内容全部删掉了?但是现在我们的所有功能是不是都没法用了?因为我们到现在还没有去实现我们的容器组件,所以说我们目前还是不能去操作redux
的。
创建容器组件
现在我们已经成功地把我们之前的组件改成一个UI
组件了,那么大家说接下来要干什么?是不是要给我们的UI
组件准备一个容器组件?只有有了容器组件我们才能跟redux
来进行交互啊。那么我们来创建一个容器组件吧。但是我们的容器组件怎么写呢?直接定义一个类组件?那肯定不行的啊,我们说了这个容器组件是直接和redux
打交道的组件,那么这里的组件不能靠我们自己写,我们就需要借助react-redux
来生成这个组件。那么我们是不是要安装这个库?npm i react-redux
,安装完这个库我们来创建这个组件吧。
import SumUI from '../../components/Sum'; import store from '../../redux/store'; import {connect} from 'react-redux'; export default connect()(SumUI);
这段代码是什么意思呢?我们来想一下,容器组件是干什么的?是不是用来使得UI
组件可以间接性地使用和操作redux
?这是不是相当于一个桥梁的作用?那么这座桥的两端是什么?是不是UI
组件和redux
?所以说我们先不管别的,最起码我们得先把我们这个桥的两端引入进来吧?所以第一行引入Sum
组件。
那么第二行我们引入redux
,我们之前在案例中是不是已经写好了我们的redux
相关的东西,总共 4 个文件,那么我们怎么引入?我们用redux
是不是一直都是store
在居中调度?不管分发动作也好,还是存储state
也好,我们是不是都是store
在做这部分内容?我们有直接来调用reducer
吗?是不是根本没有?那么这样的话,我们是不是只要引入store
就可以了?
然后后桥梁的两端都有了,是不是要把桥搭起来?这个桥怎么搭?我们说要用react-redux
来搭,我们react-redux
中有一个函数叫connect
,这个函数很好理解,桥梁是用来连接河两岸的嘛。所以说我们调用这个函数,而这个函数的返回值是一个函数,这个API
设计的就是让我们柯里化调用,当我们柯里化调用了这个函数之后,我们就可以生成一个所谓的容器组件。但是这个容器组件是谁的容器组件呢?所以说我们要把我们的UI
组件传给这个函数的返回函数。
但是我们现在先不把代码写完整,我们一步步来,我们先让容器组件和UI
组件先建立联系。那么我们现在就还用不到store
,那么我们生成了一个容器组件了,是不是要把这个容器组件暴露出去?所以最后我们export
一下。
那么当我们创建了容器组件,而且容器组件里面还有UI
组件来做子组件,那么我们是不是就要在页面上来渲染容器组件啊?不然的话我们就等于没有创建容器组件啊,一个组件你创建了不渲染,那还创建他干什么呢。所以我们修改一下App
组件中的引入就可以了。那么我们来看一下效果吧:
诶呦,报错了。这是为啥呢?报的什么错啊?说找不到store
,为什么找不到?我们说了容器组件是干什么的?是不是连接UI
组件和redux
的一个桥梁?我们把UI
组件交给了容器组件,但是我们实现连接store
了吗?是不是没有?但是我们是不是引入了store
了?但是为什么这里还会提醒我们说找不到store
呢?
因为容器组件要得到的store
不能由开发者手动去引入。所以我们把引入store
那一步给删掉。但是可能有人说了,那么我们引入了都找不到,删掉不就更找不到了嘛。别急,我来问一下,这个store
是哪个组件要用?是不是容器组件?容器组件有没有渲染?是不是在App
组件中渲染了?我们从App
组件中把store
通过props
传给容器组件才是正确的方式。那么我们来改一下吧:
import React, { Component } from 'react' import Sum from './containers/Sum' import store from './redux/store' export default class App extends Component { render() { return ( <div> <Sum store={store}/> </div> ) } }
我们在App
组件中引入store
,然后传给容器组件,来看一下效果:
这次就正常展示了页面了。以上呢就成功将UI
组件和容器组件成功连接起来了
总结
- 容器组件是连接
UI
组件和redux
的桥梁 - 容器组件要接收到
store
,但是必须通过props
传入,不可以手动引入 - 用
react-redux
提供的connect
高阶函数来创建容器组件
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/connect_ui_and_container/