实现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. oracle系列练习题

    刚学习Oracle,老师给我们布置了一些题目来练习. 题目: 创建四个表,并录入数据 1.student表 CREATE TABLE STUDENT (SNO VARCHAR(3) NOT NULL, ...

  2. ElasticSearch集群-Windows

    概述 ES集群是一个P2类型的分布式系统,除了集群状态管理以外,其他所有的请求都可以发送到集群内任意一台节点上,这个节点可以自己找到需要转发给哪些节点,并且直接跟这些节点通信.所以,从网络架构及服务配 ...

  3. B树(B-树) 、B+树

    B树(B-树) 1.B-树(B树)的基本概念B-树中所有结点中孩子结点个数的最大值成为B-树的阶,通常用m表示,从查找效率考虑,一般要求m>=3.一棵m阶B-树或者是一棵空树,或者是满足以下条件 ...

  4. echarts 的 formatter用法

    前言:formatter格式化方法.使用formatter调用自定义的数据,把内容通过处理让变成我们想要的样子. 比如,echarts数据显示是这样的(bug:部分内容被隐藏掉了,显示太长,不美观) ...

  5. 直接使用汇编编写 .NET Standard 库

    前言 Common Language Runtime(CLR)是一个很强大的运行时,它接收 Common Intermediate Language(CIL) 的输入并最终产生机器代码并执行.CIL ...

  6. GitLab Runner

    GitLab Runner是一个开源项目,用于运行你的作业(jobs)并将结果发送回GitLab.它与GitLab CI结合使用,GitLab CI是GitLab用于协调jobs的开源持续集成服务. ...

  7. hadoop之HDFS核心类Filesystem的使用

    1.导入jar包,要使用hadoop的HDFS就要导入hadoop-2.7.7\share\hadoop\common下的3个jar包和lib下的依赖包.hadoop-2.7.7\share\hado ...

  8. day18 正则表达式初学

    正则规则:客观存在的,世界上任何一种语言都能使用它. 在线测试网址:http://tool.chinaz.com/regex 正则语句:只和字符串相关,需要考虑的是:在同一个位置上可以出现的字符范围 ...

  9. Charles证书下载报Name lookup failed

    背景 1.charles https抓包需要在手机上安装证书. 2.近期疫情影响,通过openVPN远程办公. 问题现象 按照网上教程配置好charles proxy配置,证书安装的时候,iPhone ...

  10. 静态库&动态库&导入库

    我遇到的问题 先贴一个StackOverflow上的问题 上面的问题让我知道了更多动态库的知识. 我需要使用一个声音库(irrKlang)为2d游戏提供声音,我使用的编译器是mingw-w64,但是i ...