在react中使用vuex的示例代码


Posted in Javascript onJuly 30, 2018

前言

笔者最近在学习使用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判断)。

在react中使用vuex的示例代码

上图来自于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 <WrappedComponent {...props} />
   }
  }
  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不再是梦!

原文地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
一个很酷的拖动层的js类,兼容IE及Firefox
Jun 23 Javascript
ExtJs使用IFrame的实现代码
Mar 24 Javascript
Kibo 用于处理键盘事件的Javascript工具库
Oct 28 Javascript
基于jquery的跟随屏幕滚动代码
Jul 24 Javascript
利用js实现选项卡的特别效果的实例
Mar 03 Javascript
jquery动态改变onclick属性导致失效的问题解决方法
Dec 04 Javascript
用jquery等比例控制图片宽高的具体实现
Jan 28 Javascript
Bootstrap每天必学之标签页(Tab)插件
Aug 09 Javascript
Javascript循环删除数组中元素的几种方法示例
May 18 Javascript
angular中实现li或者某个元素点击变色的两种方法
Jul 27 Javascript
微信小程序文章详情页面实现代码
Sep 10 Javascript
vue简单练习 桌面时钟的实现代码实例
Sep 19 Javascript
使用JS判断移动端手机横竖屏状态
Jul 30 #Javascript
详解如何在微信小程序中愉快地使用sass
Jul 30 #Javascript
详解JSON Web Token 入门教程
Jul 30 #Javascript
JS中Promise函数then的奥秘探究
Jul 30 #Javascript
浅析java线程中断的办法
Jul 29 #Javascript
还不懂递归?读完这篇文章保证你会懂
Jul 29 #Javascript
如何在js代码中消灭for循环实例详解
Jul 29 #Javascript
You might like
PHP setcookie() cannot modify header information 的解决方法
2009/01/09 PHP
php通过array_merge()函数合并关联和非关联数组的方法
2015/03/18 PHP
thinkPHP和onethink微信支付插件分享
2019/08/11 PHP
JavaScript中的包装对象介绍
2015/01/27 Javascript
浅析javascript中的DOM
2015/03/01 Javascript
Js实现简单的小球运动特效
2016/02/18 Javascript
js获取页面引用的css样式表中的属性值方法(推荐)
2016/08/19 Javascript
javascript 玩转Date对象(实例讲解)
2017/07/11 Javascript
浅谈JS中的常用选择器及属性、方法的调用
2017/07/28 Javascript
详解nodejs中express搭建权限管理系统
2017/09/15 NodeJs
Vue 组件(component)教程之实现精美的日历方法示例
2018/01/08 Javascript
AngularJS对动态增加的DOM实现ng-keyup事件示例
2018/03/12 Javascript
Vue.js 中的 v-model 指令及绑定表单元素的方法
2018/12/03 Javascript
详解Vue 匿名、具名和作用域插槽的使用方法
2019/04/22 Javascript
jQuery删除/清空指定元素的所有子节点实例代码
2019/07/04 jQuery
Ant design vue中的联动选择取消操作
2020/10/31 Javascript
Python urlopen()函数 示例分享
2014/06/12 Python
Python连接mssql数据库编码问题解决方法
2015/01/01 Python
以Python的Pyspider为例剖析搜索引擎的网络爬虫实现方法
2015/03/30 Python
centos 安装python3.6环境并配置虚拟环境的详细教程
2018/02/22 Python
关于阿里云oss获取sts凭证 app直传 python的实例
2019/08/20 Python
PyCharm使用之配置SSH Interpreter的方法步骤
2019/12/26 Python
Django项目创建及管理实现流程详解
2020/10/13 Python
使用CSS3实现input多选框自定义样式的方法示例
2019/07/19 HTML / CSS
CSS3中的弹性布局em运用入门详解 1em等于多少像素
2021/02/08 HTML / CSS
html5播放视频且动态截图实现步骤与代码(支持safari其他未测试)
2013/01/06 HTML / CSS
巴西电子产品购物网站:Saldão da Informática
2018/01/09 全球购物
英国最大的在线蜡烛商店:Candles Direct
2019/03/26 全球购物
创立科技Java面试题
2015/11/29 面试题
学习雷锋月活动总结
2014/07/03 职场文书
个人授权委托书模板
2014/09/14 职场文书
好好学习保证书
2015/02/26 职场文书
幼儿园班级工作总结2015
2015/05/25 职场文书
呐喊读书笔记
2015/06/30 职场文书
解决Mysql的left join无效及使用的注意事项说明
2021/07/01 MySQL
python和anaconda的区别
2022/05/06 Python