摘要:原文地址前言笔者最近在学习使用,提到就绕不过去。同时应当注意,当组件时应当重新收集依赖,因为之后依赖关系很可能已经变化了清空依赖至此,我们的小目标已经完成了,在中使用不再是梦
原文地址
前言笔者最近在学习使用react,提到react就绕不过去redux。redux是一个状态管理架构,被广泛用于react项目中,但是redux并不是专为react而生,两者还需要react-redux建立一座桥梁。同时,redux架构规定只能发送同步action,要想发送异步action就需要结合中间件如redux-thunk、redux-saga等,所以说要想搞定redux还真是不容易啊,光名词就这么多。笔者以前也接触过一点vuex,vuex对笔者这样的菜鸡相对友好,但是vuex是和vue配套的,是不可能用在react中的,这辈子都别想用在react中。但是我不服,那么这篇文章就探索下如何制作一个可以在react中使用的类似vuex的状态管理工具,我将它取名为reux。
vuex <=> redux + react-redux + redux-saga正文
响应式数据观测系统
vue的一大特色就是响应式数据观测系统,它可以在get数据时收集依赖,在set数据时触发更新。vuex借助于vue的数据观测系统,可以轻松的收集数据依赖,并且依赖可以精细到组件的粒度,也就是说某一状态改变时,只有依赖到这一状态的组件才会触发rerender,这样看来redux体系就比较傻,只要提交action,就会从根组件rerender(react-redux内部自动进行shouldCompoentUpdate判断)。
上图来自于vue官网对vuex架构的说明,链接。
上图中的component是vue component,只要vue component执行render,那么vuex的数据响应系统就可以自动的收集依赖,当状态改变时,依赖于此状态的组件就会重新渲染。既然我们要实现的是一个类vuex的状态管理工具,即支持以get的方式收集依赖,以set的方式触发更新,所以reux利用了vue的响应式数据观测系统,正所谓前人种树,后人乘凉。
如何收集依赖
我们已经有了响应式数据系统,接下来要解决的问题就是如何收集依赖,收集依赖必须要触发get,而触发get的前提是组件可以拿到store,因此第一步是向组件注入store。类似react-redux,reux提供了Provider使子组件可以拿到store。
class Provider extends Component { getChildContext() { return {store: this.props.store}; } render() { const { children } = this.props; return children; } } Provider.childContextTypes = { store: PropTypes.object };
相应的子组件可以context拿到store,如下
class Child extends Component { render() { // store => this.context.store } } Child.contextTypes = { store: PropTypes.object };
这样写的缺点显而易见,每个子组件都需要定义contextTypes,同样的类似于react-redux,reux提供了connect函数,用于映射state => props
const connect = (mapStateToProps = () => {}) => { return (WrappedComponent) => { const Wrapper = class extends Component { render() { const store = this.context.store; const props = Object.assign({}, this.props, mapStateToProps(store.state, this.props), {dispatch: store.dispatch, commit: store.commit}); return} } Wrapper.contextTypes = { store: PropTypes.object }; reaturn Wrapper; } }
这样一来,只要组件执行render方法,便会触发get钩子,从而使得store自动收集依赖,我们再想下依赖是什么,其实依赖应该是组件实例,那么当set钩子触发时,每个依赖(即组件实例)只要执行forceUpdate方法就可以达到rerender的效果。
但是问题是,get钩子触发时,如何确定依赖到底是谁呢?借鉴vue,我们定义一个stack,当componentWillMount时进栈,当componentDidMount时出栈
componentWillMount() { pushTarget(this); } componentDidMount() { popTarget(this); }
这样当get钩子触发时,当前target就是目标依赖。同时应当注意,当组件update时应当重新收集依赖,因为update之后依赖关系很可能已经变化了
update() { // 清空依赖 this.clear(); pushTarget(this); this.forceUpdate(() => { popTarget(this); }) }
至此,我们的小目标已经完成了,在react中使用vuex不再是梦!
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/96381.html
摘要:我在中写了这段代码在组件被创建时候将会执行此函数相当于进入页面的自执行使用方法监听属性并执行一个回调函数按道理在元素被创建的时候,会将监听到的值赋给并且打印。 天地不仁以万物为刍狗,宇宙无义视众生如蝼蚁 ——萧鼎和我 上一节列出了5个关键点,第一个路由已经解决了,接下来解决第二个问题: 组件的通信问题 一、组件的关系 组件之间的关系无非就是两种父子关系...
摘要:也就是说不应该有公开的,所有都应该是私有的,只能有公开的。允许使用方法设置监听函数,一旦发生变化,就自动执行这个函数。用一个叫做的纯函数来处理事件。可以通过得到当前状态。在中,同步的表现就是发出以后,立即算出。 这篇文章试着聊明白这一堆看起来挺复杂的东西。在聊之前,大家要始终记得一句话:一切前端概念,都是纸老虎。 不管是Vue,还是 React,都需要管理状态(state),比如组件之...
摘要:说到老四了,最苦逼的家伙了,活都让他干了,活总得干完一个说一个吧,所以他基本上同步进行的。 前言 这次发表的项目,这对我来说是一场革命。记录着第一次GitHub发布项目,记录着最初学习vuex的头昏脑胀,也记录着怀揣对react的一腔热血后却步履阑珊后,再次回看vue时那种感觉。所以说这个项目对我很有意思,麻雀虽小,五脏俱全。 在写这个项目之前,我正在试水react,那种函数式编程+j...
摘要:将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库。此示例使用类似的语法,称为。执行更快,因为它在编译为代码后进行了优化。基于的模板使得将已有的应用逐步迁移到更为容易。 前言 因为没有明确的界定,这里不讨论正确与否,只表达个人对前端MV*架构模式理解看法,再比较React和Vue两种框架不同.写完之后我知道这文章好水,特别是框架对比部分都是别人说烂的,而我也是打算把...
摘要:在模式中一般把层算在层中,只有在理想的双向绑定模式下,才会完全的消失。层将通过特定的展示出来,并在控件上绑定视图交互事件,一般由框架自动生成在浏览器中。三大框架的异同三大框架都是数据驱动型的框架及是双向数据绑定是单向数据绑定。 MVVM相关概念 1) MVVM典型特点是有四个概念:Model、View、ViewModel、绑定器。MVVM可以是单向绑定也可以是双向绑定甚至是不绑...
阅读 2524·2023-04-25 19:47
阅读 3347·2019-08-29 17:18
阅读 835·2019-08-29 15:26
阅读 3344·2019-08-29 14:17
阅读 1050·2019-08-26 13:49
阅读 3282·2019-08-26 13:22
阅读 2984·2019-08-26 10:44
阅读 2678·2019-08-23 16:51