自定义React-redux
实现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的更多相关文章
- webpack+react+redux+es6开发模式
一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...
- webpack+react+redux+es6
一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...
- ReactJS React+Redux+Router+antDesign通用高效率开发模板,夜间模式为例
工作比较忙,一直没有时间总结下最近学习的一些东西,为了方便前端开发,我使用React+Redux+Router+antDesign总结了一个通用的模板,这个技术栈在前端开发者中是非常常见的. 总的来说 ...
- react + redux 完整的项目,同时写一下个人感悟
先附上项目源码地址和原文章地址:https://github.com/bailicangd... 做React需要会什么? react的功能其实很单一,主要负责渲染的功能,现有的框架,比如angula ...
- 看了就学会之React redux入门示例
环境准备 为了方便,这里使用create-react-app搭建react环境 create-react-app mydemo 弹出配置 如果需要自定义react的配置,需要运行下面的命令把配置文件弹 ...
- react+redux教程(六)redux服务端渲染流程
今天,我们要讲解的是react+redux服务端渲染.个人认为,react击败angular的真正“杀手锏”就是服务端渲染.我们为什么要实现服务端渲染,主要是为了SEO. 例子 例子仍然是官方的计数器 ...
- react+redux教程(五)异步、单一state树结构、componentWillReceiveProps
今天,我们要讲解的是异步.单一state树结构.componentWillReceiveProps这三个知识点. 例子 这个例子是官方的例子,主要是从Reddit中请求新闻列表来显示,可以切换reac ...
- react+redux官方实例TODO从最简单的入门(6)-- 完结
通过实现了增-->删-->改-->查,对react结合redux的机制差不多已经了解,那么把剩下的功能一起完成吧 全选 1.声明状态,这个是全选状态 2.action约定 3.red ...
- react+redux官方实例TODO从最简单的入门(1)-- 前言
刚进公司的时候,一点react不会,有一个需求要改,重构页面!!!完全懵逼,一点不知道怎么办!然后就去官方文档,花了一周时间,就纯react实现了页面重构,总体来说,react还是比较简单的,由于当初 ...
- 重写官方TodoList,对于初学react+redux的人来说,很有好处
虽然官网的TodoList的例子写的很详细,但是都是一步到位,就是给你一个action,好家伙,全部都写好了,给你一个reducer,所有功能也是都写好了,但是我们这些小白怎么可能一下就消化那么多,那 ...
随机推荐
- 4.【Spring Cloud Alibaba】服务容错-sentinel
雪崩效应 常见容错方案 超时 限流 仓壁模式 断路器模式 断路器三态转换 使用Sentinel实现容错 什么是Sentinel https://github.com/alibaba/Sentinel ...
- 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"问题 ...
- IO流之File对象
File类: 用来将文件或者文件夹封装成对象 方便对文件与文件夹的属性等信息进行操作(因为流只能操作文件中的数据) File对象可以作为参考传递给流的构造函数 上下级文件夹之间使用分隔符分开: 在Wi ...
- 关于simplememory theme的设置和感想
前言 首先,这是我第一次自己个性化博客的主题.如果下文所写如有不妥之处还望大佬指出 参考 这次设置多亏了GitHub上的开源代码:https://github.com/BNDong/Cnblogs-T ...
- linux文件系统相关命令(df/du/fsck/dumpe2fs)
一.文件系统查看命令df 格式 df [选项] [挂载点] 选项 名称 作用 -a 显示所有的文件系统信息,包括特殊文件系统,如/proc,/sysfs -h 使用习惯单位显示容量,如KB,MB或GB ...
- 何时使用异步或同步AJAX
通常最好使用异步调用 通过优锐课核心java学习笔记中,我们可以看到,码了很多专业的相关知识, 分享给大家参考学习. AJAX代表异步JavaScript和XML,是一项允许异步更新网页的技术,这意味 ...
- eclipse中一个项目引用另一个项目的方法
我们在开发的时候,有时候需要把一个大的项目打散,尤其是现在微服务的架构很流行,一个大的项目往往被拆成很多小的项目,而有的项目作为公共工程被独立出来,比如有个工程专门提供各种Util工具类,有的工程专门 ...
- [Contract] Solidity 判断 mapping 值的存在
比如 mapping(address => uint) tester,只需要判断 mapping 是否为默认值 0, tester[msg.sender] == 0 "You can ...
- 从 0 使用 SpringBoot MyBatis MySQL Redis Elasticsearch打造企业级 RESTful API 项目实战
大家好!这是一门付费视频课程.新课优惠价 699 元,折合每小时 9 元左右,需要朋友的联系爱学啊客服 QQ:3469271680:我们每课程是明码标价的,因为如果售价为现在的 2 倍,然后打 5 折 ...
- Java中Thread方法启动线程
public class ThreadTest extends Thread { private int count = 10; @Override public void run() { //重写 ...