实现一个自己的react-redux
2017-11-26 23:23
1126 查看
Redux
相关概念
Redux是一种新型的前端“架构模式”。经常和 React.js 一并提出,如果要使用 React.js 基本都要伴随着 Redux 和 React.js 结合的库 React-redux。要注意的是,Redux 和 React-redux 并不是同一个东西。Redux 是一种架构模式(Flux 架构的一种变种),它不关注你到底用什么库,你可以把它应用到 React 和 Vue,甚至跟 jQuery 结合都没有问题。而 React-redux 就是把 Redux 这种架构模式和 React.js 结合起来的一个库,就是 Redux 架构在 React.js 中的体现
。
可以这么理解,Redux就是一个用于共享状态管理的工具,就是一个保存了许多数据的js。既然说到共享状态管理,在不引入Redux时,我们通常会这么做:
1. 共享状态不就是指有一些状态需要被的多个组件所共用吗?并且这个状态还会需要被改变。那我们直接把这个状态放在这些下级组件所共有的祖先组件就行了,然后通过将改变状态的函数通过props传递给下级组件就行了。如果层级不深的话,这样做是可行的。但是往往我们的组件层级都会达到3、4层甚至更多。这个时候通过props方式来调用或者改变状态就会变得非常繁杂。
可以使用上下文,但是官方不推荐。原因大概是使用context修改共享状态太容易了,基本无门槛。修改了状态很难追溯到源头,导致维护和调试变得复杂“。
所以对于Redux的作用可以归纳为:
不容易的修改共享状态
有门槛的修改共享状态
高调(大张旗鼓的调用修改reducer)的修改共享状态
使修改状态容易被追溯
在实现Redux之前,先了解几个跟Redux相关的概念:
1. Provider
2. createStore
3. connect
4. store(subscriber、getState、dispatch)
上述概念各自的作用:
1. Provider:用于提共享状态的一个纯组件而已
2. createStore: 用于创建store即包含了共享状态和dispatch的对象
3. connect: 用于将普通组件改造成能接收并且修改共享状态的一个纯函数
4. store: 只是一个名字真正重要的是括号中的东西。subscriber:订阅者模式中的订阅者,用于添加回调函数。getState:对外公共方法,用于提供共享状态。dispatch:用于修改共享状态。
编码实现
创建redux.js、
react-redux.js。
编辑
redux.js:
/** * 用于创建store * @param reducer 用户自己创建的reducer */ function createStore(reducer) { var state = null; var listeners = []; //dispatc a9d3 h用于派发事件,action包含type和用户自定义的状态信息 var dispatch = function(action) { //更新共享状态 state = reducer(state,action); //派发监听事件 listeners.forEach(function(listener) { listener(); }); }; //订阅者模式,用于实现共享状态更新后,通知React进行更新 var subscriber = function(listener) { listeners.push(listener); }; //用于提供state var getState = function() { return state; }; //首次调用,用于初始化共享状态的值 dispatch(); return { dispatch: dispatch, subscriber: subscriber, getState: getState }; } export default createStore;
react-redux.js:
import React,{Component} from 'react'; import PropTypes from 'prop-types'; /** * Provider只是一个用于提供上下文的组件 */ export class Provider extends Component { static childContextTypes = { store: PropTypes.object } getChildContext() { return { store: this.props.store } } render() { return ( <div>{this.props.children}</div> ) } } /** * connect接收用户自定义的mapStateToProps,mapDispatchToProps * mapStateToProps,mapDispatchToProps用于将state及dispatch以用户自定义的方式提供。 */ export var connect = function(mapStateToProps,mapDispatchToProps) { return function(WrapperComponent) { class ConnectComponent extends Component { static contextTypes = { store: PropTypes.object } constructor(props) { super(props); this.state = { allProps: {} } } componentWillMount() { //添加监听函数,用于在共享状态改变之后调用以使组件更新 this.context.store.subscriber(()=>this.updateProps()); //初始调用,以使组件获取共享状态的初始值 this.updateProps(); } updateProps() { var store = this.context.store; //通过mapStateToProps,mapDispatchToProps来分发共享状态 var stateProps = mapStateToProps?mapStateToProps(store.getState()):{}; var dispatchProps = mapDispatchToProps?mapDispatchToProps(store.dispatch):{}; this.setState({ allProps: { ...this.props, ...stateProps, ...dispatchProps } }); } render() { //将用户需要的共享状态和上级传入的属性、修改状态的事件以props的形式传递 return (<WrapperComponent {...this.state.allProps}/>) } } return ConnectComponent; } }
接下来可以像使用react-redux一样使用它们,但是并不完全包含官方Redux所具备的功能。实际上redux和react-redux的实现比这个要复杂的多,例如可以使用中间件等。
参考文档:
http://huziketang.com/books/react/lesson30
相关文章推荐
- react初学者福利来了:react+redux实现一个列表的静态应用
- 原生实现一个react-redux的代码示例
- 自己实现一个shell
- 一个简单的例子让你了解React-Redux
- 创建一个数组, 实现函数init()初始化数组、 实现reverse()函数完成数组元素的逆置,实现empty()清空数组。要求:自己设计函数的参数,返回值。
- 基于react-redux开发一个待办事项的demo–todoList的笔记
- 尝试自己动手用react来写一个分页组件
- 自己动手实现一个队列LGQueue(刚刚)
- [置顶] Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能。
- 彻底理解Promise对象——用es5语法实现一个自己的Promise(上篇)
- 使用react-native做一个简单的应用-06商品界面的实现
- 给自己一个机会,让我们帮你实现梦想
- [React-章节11 终结篇] 做一个留言板项目 之 重构至redux
- [原创]自己动手实现React-Native下拉框控件
- 对session的原理解释以及自己实现一个session
- 自己实现的一个不会奇奇怪怪换行的TextView.
- 自己实现一个简单的优先队列-二叉堆
- 练习:自己动手实现一个轻量级的信号量(一)
- //1.实现一个函数,打印乘法口诀表,口诀表的行数和列数自己指定, //输入9,输出9 * 9口诀表,输出12,输出12 * 12的乘法口诀表。
- 自己实现一个内存缓存