实现mini版react-redux

1. 理解react-redux模块

 1). react-redux模块整体是一个对象模块
2). 包含2个重要属性: Provider和connect
3). Provider
值: 组件类
作用: 向所有容器子组件提供全局store对象
使用: <Provider store={store}><Xxx/></Provider>
4). connect
值: 高阶函数
作用: 包装组件生成容器组件, 让被包装组件能与redux进行通信
使用: connect(mapStateToProps, mapDispatchToProps)(Xxx)

2. context的理解和使用

1). 理解
当你觉得多层传递props麻烦, 可以选择使用context
context是组件对象的一个属性, 它的值是一个对象
一个组件指定的context内数据, 所有层次子组件都可以读取到
如果可以尽量不用context, 你可以选择使用react-redux, react-redux内部就利用了context
2). 使用
父组件:
static childContextTypes = {
color: PropTypes.string
}
getChildContext() {
return {color: 'red'};
}
后代组件:
static contextTypes = {
color: PropTypes.string
} render () {
this.context.color
}

3. 实现代码: src/libs/react-redux/index.js

import React, {Component} from 'react'
import PropTypes from 'prop-types' /*
1. Provider组件类
*/
export class Provider extends Component {
// 声明当前组件接收store
static propTypes = {
store: PropTypes.object.isRequired
} // 必须声明向子节点指定全局数据store
static childContextTypes = {
store: PropTypes.object.isRequired
} // 指定向子组件指定全局数据store
getChildContext() {
return {store: this.props.store};
} render() {
// 返回所有子节点(如果没有子节点返回undefined, 如果只有一个子节点它是对象, 如果有多个它是数组)
return this.props.children
}
} /*
2. connect方法
*/
export function connect(mapStateToProps = () => null, mapDispatchToProps = {}) {
// 返回函数(接收被包装组件类作为参数)
return (WrapComponent) => {
// 返回一个新的组件类
return class ConnectComponent extends Component {
// 声明接收全局store
static contextTypes = {
store: PropTypes.object.isRequired
} // 构造函数的第2个参数为context对象
constructor(props, context) {
super(props)
console.log('constructor', this.context) // 此时组件对象中还没有context
// 从context中取出store
const {store} = context
// 一般属性: 调用mapStateToProps函数得到包含所有需要传递一般属性的集合对象
const stateProps = mapStateToProps(store.getState())
// 分发action的函数属性: 调用自定义的整合函数生成包含多个分发action的函数的对象
const dispatchProps = this.bindActionCreators(mapDispatchToProps) // 初始化状态, 包含所有需要传递给WrapComponent组件的一般属性
this.state = {
...stateProps
}
// 将包含dispatch函数的对象保存在组件对象上(不用放到state中)
this.dispatchProps = dispatchProps
} /*
根据包含多个action creator的对象, 返回一个包含多个分发action的函数的对象
*/
bindActionCreators = (mapDispatchToProps) => {
// 准备一个保存分发action函数的对象容器
const dispatchProps = {}
// 遍历每个action creator
Object.keys(mapDispatchToProps).forEach((key) => {
// 得到某个action creator
const actionCreator = mapDispatchToProps[key]
//定义包含分发action代码的函数, 并只在到准备好的容器中
dispatchProps[key] = (...args) => {
this.context.store.dispatch(actionCreator(...args))
}
})
// 返回dispatch代码函数容器对象
return dispatchProps
} componentDidMount() {
console.log('componentDidMount', this.constructor)
// 得到store
const {store} = this.context
// 订阅监听
store.subscribe(() => {
// 一旦store中的state有变化, 更新组件状态, 从而导致被包装组件重新渲染
this.setState(mapStateToProps(store.getState()))
})
} render() {
return <WrapComponent {...this.state} {...this.dispatchProps} />
}
}
}
}

自定义React-redux的更多相关文章

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

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

  2. webpack+react+redux+es6

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

  3. ReactJS React+Redux+Router+antDesign通用高效率开发模板,夜间模式为例

    工作比较忙,一直没有时间总结下最近学习的一些东西,为了方便前端开发,我使用React+Redux+Router+antDesign总结了一个通用的模板,这个技术栈在前端开发者中是非常常见的. 总的来说 ...

  4. react + redux 完整的项目,同时写一下个人感悟

    先附上项目源码地址和原文章地址:https://github.com/bailicangd... 做React需要会什么? react的功能其实很单一,主要负责渲染的功能,现有的框架,比如angula ...

  5. 看了就学会之React redux入门示例

    环境准备 为了方便,这里使用create-react-app搭建react环境 create-react-app mydemo 弹出配置 如果需要自定义react的配置,需要运行下面的命令把配置文件弹 ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 4.【Spring Cloud Alibaba】服务容错-sentinel

    雪崩效应 常见容错方案 超时 限流 仓壁模式 断路器模式 断路器三态转换 使用Sentinel实现容错 什么是Sentinel https://github.com/alibaba/Sentinel ...

  2. Linux安装Redis,在测试阶段即make test出现“You need tcl 8.5 or newer in order to run the Redis test”问题解决方案

    Linux安装Redis,在测试阶段即make test出现"You need tcl 8.5 or newer in order to run the Redis test"问题 ...

  3. IO流之File对象

    File类: 用来将文件或者文件夹封装成对象 方便对文件与文件夹的属性等信息进行操作(因为流只能操作文件中的数据) File对象可以作为参考传递给流的构造函数 上下级文件夹之间使用分隔符分开: 在Wi ...

  4. 关于simplememory theme的设置和感想

    前言 首先,这是我第一次自己个性化博客的主题.如果下文所写如有不妥之处还望大佬指出 参考 这次设置多亏了GitHub上的开源代码:https://github.com/BNDong/Cnblogs-T ...

  5. linux文件系统相关命令(df/du/fsck/dumpe2fs)

    一.文件系统查看命令df 格式 df [选项] [挂载点] 选项 名称 作用 -a 显示所有的文件系统信息,包括特殊文件系统,如/proc,/sysfs -h 使用习惯单位显示容量,如KB,MB或GB ...

  6. 何时使用异步或同步AJAX

    通常最好使用异步调用 通过优锐课核心java学习笔记中,我们可以看到,码了很多专业的相关知识, 分享给大家参考学习. AJAX代表异步JavaScript和XML,是一项允许异步更新网页的技术,这意味 ...

  7. eclipse中一个项目引用另一个项目的方法

    我们在开发的时候,有时候需要把一个大的项目打散,尤其是现在微服务的架构很流行,一个大的项目往往被拆成很多小的项目,而有的项目作为公共工程被独立出来,比如有个工程专门提供各种Util工具类,有的工程专门 ...

  8. [Contract] Solidity 判断 mapping 值的存在

    比如 mapping(address => uint) tester,只需要判断 mapping 是否为默认值 0, tester[msg.sender] == 0 "You can ...

  9. 从 0 使用 SpringBoot MyBatis MySQL Redis Elasticsearch打造企业级 RESTful API 项目实战

    大家好!这是一门付费视频课程.新课优惠价 699 元,折合每小时 9 元左右,需要朋友的联系爱学啊客服 QQ:3469271680:我们每课程是明码标价的,因为如果售价为现在的 2 倍,然后打 5 折 ...

  10. Java中Thread方法启动线程

    public class ThreadTest extends Thread {  private int count = 10; @Override public void run() { //重写 ...