You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
classProviderextendsComponent{getChildContext(){return{store: this.props.store};}render(){const{ children }=this.props;returnchildren;}}Provider.childContextTypes={store: PropTypes.object};
相应的子组件可以context拿到store,如下
classChildextendsComponent{render(){// store => this.context.store}}Child.contextTypes={store: PropTypes.object};
原文地址
前言
笔者最近在学习使用
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。正文
响应式数据观测系统
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。相应的子组件可以context拿到store,如下
这样写的缺点显而易见,每个子组件都需要定义contextTypes,同样的类似于react-redux,reux提供了
connect
函数,用于映射state => props这样一来,只要组件执行render方法,便会触发
get
钩子,从而使得store自动收集依赖,我们再想下依赖是什么,其实依赖应该是组件实例,那么当set
钩子触发时,每个依赖(即组件实例)只要执行forceUpdate方法就可以达到rerender的效果。但是问题是,
get
钩子触发时,如何确定依赖到底是谁呢?借鉴vue,我们定义一个stack,当componentWillMount
时进栈,当componentDidMount
时出栈这样当
get
钩子触发时,当前target就是目标依赖。同时应当注意,当组件update时应当重新收集依赖,因为update之后依赖关系很可能已经变化了至此,我们的小目标已经完成了,在react中使用vuex不再是梦!
The text was updated successfully, but these errors were encountered: