一、定义与功能

React-Redux 将所有组件分成两大类:UI 组件(presentational component)和容器组件(container component)

1、UI 组件特征:

  • 只负责 UI 的呈现,不带有任何业务逻辑
  • 没有状态(即不使用this.state这个变量)
  • 所有数据都由参数(this.props)提供
  • 不使用任何 Redux 的 API

2、容器组件特征:

  • 负责管理数据和业务逻辑,不负责 UI 的呈现
  • 带有内部状态
  • 使用 Redux 的 API

总结:

UI 组件负责 UI 的呈现,容器组件负责管理数据和逻辑。

React-Redux 规定,所有的 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成。也就是说,用户负责视觉层,状态管理则是全部交给它。

二、使用与方法

1、connect方法  输入UI组件, 输出容器组件

React-Redux 提供connect方法,用于从 UI 组件生成容器组件。

// TodoList-> UI组件; VisibleTodoList -> 容器组件
// mapStatetoProps,mapDispatchToProps -> 它们定义了 UI 组件的业务逻辑。
// mapStatetoProps 可省略,若省略,UI 组件就不会订阅Store,就是说 Store 的更新不会引起 UI 组件的更新
import { connect } from 'react-redux'
const VisibleTodoList = connect(mapStatetoProps, mapDispatchToProps)(TodoList);

(1)  mapStateToProps(state [,props]) 负责输入逻辑,即将state映射到 UI 组件的参数(props

state: 必选,state对象;props: 可选,代表容器组件的props对象
mapStateToProps会订阅 Store,每当state更新的时候,就会自动执行,重新计算 UI 组件的参数(props),从而触发 UI 组件的重新渲染。

// map Redux state to component props (把 Redux state 映射到 component props)
const mapStatetoProps = (state) => {
return {num: state}
}
// 使用ownProps作为参数后,若容器组件的参数(ownProps)发生变化,也会引发 UI 组件重新渲染
const mapStateToProps = (state, ownProps) => {
return {
active: ownProps.filter === state.visibilityFilter
}
}

(2) mapDispatchToProps 负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。

// map Redux actions to component props (把 Redux actions 映射到 component props)
const mapDispatchToProps = dispatch => {
return {
onIncreaseClick: () => dispatch(increaseAction)
};
}

mapDispatchToProps 分为两种类型:函数和对象

mapDispatchToProps是一个函数,会得到dispatchownProps(容器组件的props对象)两个参数。

mapDispatchToProps作为函数,应该返回一个对象,该对象的每个键值对都是一个映射,定义了 UI 组件的参数怎样发出 Action

const mapDispatchToProps = (
dispatch,
ownProps
) => {
return {
onClick: () => {
dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: ownProps.filter
});
}
};
}

mapDispatchToProps是一个对象,键名是对应 UI 组件的同名参数,键值应该是一个函数,会被当作 Action creator ,返回的 Action 会由 Redux 自动发出

const mapDispatchToProps = {
onClick: (filter) => {
type: 'SET_VISIBILITY_FILTER',
filter: filter
};
}

三、原理与流程

为了让子组件能够获得context属性,React强制要求根组件(此处为Provider组件)提供getChildContext实例方法,以及类属性childContextTypes。而子组件想要获取context,也必须定义类级别的Counter. contextTypes属性。定义是双向的,如果缺少了任何一块,子组件都获取不到context属性。

我认为父组件的那块定义是在Provider的代码中实现的,而子组件的那部分是在connect方法中实现的。

因此connect方法为Counter组件添加的context属性实质上是由Provider传下来的,这样在mapStatesToProps方法里的state参数实质上就是this.context.store.getState()方法获得的。

页面首次加载以及之后有互动行为之后整个逻辑的流程:

(1)页面首次加载时,store里的初始state获取过程:
createStore(reducers,defaultParams)的调用,其中reducers可以使一个reducer,也可是redux.combineReducers过的reducer的集合。

createStore方法会对每个reducer去dispatch一个action.type=@@redux/INIT类型的action,而这个action一般在reducer的代码里不会被handle,直接掉入default块,于是就返回了state的初始状态。

然后一般就会ReactDom.render()将应用渲染出来,每个子组件的容器组件通过传入this.context.store.getState()方法获得的state对象, 以及容器组件上自带的ownProps给mapStatesToProperties方法,来构建props,最后将props应用到子组件的UI组件上。

(2)互动行为之后整个逻辑:

当在子组件上发生交互行为,如click时,mapDispatchToProps会定义click触发时应该dispatch哪一个action的映射。
然后store接收到这个action后会进行reduce,得到最新的state,然后再调用所有的子组件的mapStatesToProps方法生成新的props。
最后对Provider进行重新渲染。当然上面的事件计算出来的很多state可能都不会发生变化,所以diff算法不会去修改这些没有发生变化的组件,因此性能也比较好。

 

React-Redux 总结的更多相关文章

  1. webpack+react+redux+es6开发模式

    一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...

  2. react+redux教程(六)redux服务端渲染流程

    今天,我们要讲解的是react+redux服务端渲染.个人认为,react击败angular的真正“杀手锏”就是服务端渲染.我们为什么要实现服务端渲染,主要是为了SEO. 例子 例子仍然是官方的计数器 ...

  3. react+redux教程(五)异步、单一state树结构、componentWillReceiveProps

    今天,我们要讲解的是异步.单一state树结构.componentWillReceiveProps这三个知识点. 例子 这个例子是官方的例子,主要是从Reddit中请求新闻列表来显示,可以切换reac ...

  4. react+redux官方实例TODO从最简单的入门(6)-- 完结

    通过实现了增-->删-->改-->查,对react结合redux的机制差不多已经了解,那么把剩下的功能一起完成吧 全选 1.声明状态,这个是全选状态 2.action约定 3.red ...

  5. react+redux官方实例TODO从最简单的入门(1)-- 前言

    刚进公司的时候,一点react不会,有一个需求要改,重构页面!!!完全懵逼,一点不知道怎么办!然后就去官方文档,花了一周时间,就纯react实现了页面重构,总体来说,react还是比较简单的,由于当初 ...

  6. 重写官方TodoList,对于初学react+redux的人来说,很有好处

    虽然官网的TodoList的例子写的很详细,但是都是一步到位,就是给你一个action,好家伙,全部都写好了,给你一个reducer,所有功能也是都写好了,但是我们这些小白怎么可能一下就消化那么多,那 ...

  7. react+redux教程(四)undo、devtools、router

    上节课,我们介绍了一些es6的新语法:react+redux教程(三)reduce().filter().map().some().every()....展开属性 今天我们通过解读redux-undo ...

  8. react+redux教程(三)reduce()、filter()、map()、some()、every()、...展开属性

    reduce().filter().map().some().every()....展开属性   这些概念属于es5.es6中的语法,跟react+redux并没有什么联系,我们直接在https:// ...

  9. react+redux教程(二)redux的单一状态树完全替代了react的状态机?

    上篇react+redux教程,我们讲解了官方计数器的代码实现,react+redux教程(一).我们发现我们没有用到react组件本身的state,而是通过props来导入数据和操作的. 我们知道r ...

  10. react+redux教程(一)connect、applyMiddleware、thunk、webpackHotMiddleware

    今天,我们通过解读官方示例代码(counter)的方式来学习react+redux. 例子 这个例子是官方的例子,计数器程序.前两个按钮是加减,第三个是如果当前数字是奇数则加一,第四个按钮是异步加一( ...

随机推荐

  1. WPF prism 类、属性和方法的导入和导出

    学习Prism一定要掌握依赖注入的应用,只有了解了Prism的依赖注入才能更好的使用Prism提升应用开发的架构. 首先说明Prism依赖注入有两种方式及MEF和Unity ,在Prism中是两个没有 ...

  2. vue v-for直接循环数字

    <svg class="icon" aria-hidden="true" v-for="index of 5" :key=" ...

  3. JS实战篇

    实现选项卡的选择: 效果图如下: 代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8& ...

  4. beego框架学习(三) -orm的使用

    2 3 4 5 6 7 8 9 10 11 目前beego-orm支持的数据有: - MySQL:https://github.com/go-sql-driver/mysql - PostgreSQL ...

  5. get、set快捷键那码事儿

    今天发现一个省时间的方法.get一下,哈哈 在快捷get/set.或其他那个页面上的方法时,只需Shift+Alt+s 然后,选择哪个方法,就按该方法字母下有横线的那个字母(只按单个字母就行) 在ge ...

  6. 解决reportNG中文乱码(转:http://www.it610.com/article/3626590.htm)

    1.下载reportng源码      git clone  https://github.com/dwdyer/reportng.git 2.修改AbstractReporter.java      ...

  7. [转帖]yum 下载rpm包 之前不知道具体的存放路径.

    使用Yum下载RPM包-进击的二狗子-51CTO博客 https://www.2cto.com/os/201905/807225.html yumdownloader 命令 yum install y ...

  8. Linux下面MariaDB 管理命令基础使用

    MariaDB 是 MySQL 的一个分,由于某些原因,使之取代了Mysql成为了 RHEL/CentOS 7 的默认数据库.针对数据库的操作我们经常做的操作就是增删查改,接下来就介绍下 MariaD ...

  9. mongodb增删改查常用命令总结

    前言 去年我还折腾过mongodb,后来用不到也就没碰了,这就导致了我忘的一干二净,不得不感叹,编程这东西只要不用,就会忘没了.现在我想重拾mongodb,来总结一下常用命令,主要就是增删改查. 另外 ...

  10. MFC,QT与WinForm,WPF简介

    编程语言的组成编程语言做为一种语言自然和英语这些自然语言有类似的地方.学英语时我们知道要先记26个字母,然后单词及其发音,接下来就是词组,句子.反正简单的说就是记单词,熟悉词法,句法.接下来就是应用了 ...