在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 相关文章推荐
防止页面被iframe(兼容IE,Firefox火狐)
Jul 04 Javascript
兼容主流浏览器的iframe自适应高度js脚本
Jan 10 Javascript
jQuery实现下拉框左右选择的简单实例
Feb 22 Javascript
jquery事件preventDefault()方法用法实例
Jan 16 Javascript
js控制输入框获得和失去焦点时状态显示的方法
Jan 30 Javascript
setTimeout内不支持jquery的选择器的解决方案
Apr 28 Javascript
Listloading.js移动端上拉下拉刷新组件
Aug 04 Javascript
js完整倒计时代码分享
Sep 18 Javascript
React创建组件的三种方式及其区别
Jan 12 Javascript
小程序如何在不同设备上自适应生成海报的实现方法
Aug 20 Javascript
layui 富文本赋值,取值,取纯文本值的实例
Sep 18 Javascript
vue v-for 点击当前行,获取当前行数据及event当前事件对象的操作
Sep 10 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
基于pear auth实现登录验证
2010/02/26 PHP
php 文件上传类代码
2011/08/06 PHP
php实现查询百度google收录情况(示例代码)
2013/08/02 PHP
微信公众号支付之坑:调用支付jsapi缺少参数 timeStamp等错误解决方法
2016/01/12 PHP
纯CSS3实现质感细腻丝滑按钮
2021/03/09 HTML / CSS
js 浏览器事件介绍
2012/03/30 Javascript
用JS提交参数创建form表单在FireFox中遇到的问题
2013/01/16 Javascript
js 程序执行与顺序实现详解
2013/05/13 Javascript
JavaScript对内存分配及管理机制详细解析
2013/11/11 Javascript
解析Javascript中中括号“[]”的多义性
2013/12/03 Javascript
js右下角弹出提示框示例代码
2016/01/12 Javascript
JavaScript操作表单实例讲解(上)
2016/06/20 Javascript
Javascript随机标签云代码实例
2016/06/21 Javascript
js简单时间比较的方法
2016/08/02 Javascript
详解XMLHttpRequest(二)响应属性、二进制数据、监测上传下载进度
2016/09/14 Javascript
JavaScript正则表达式小结(test|match|search|replace|split|exec)
2016/12/08 Javascript
从零开始学习Node.js系列教程之SQLite3和MongoDB用法分析
2017/04/13 Javascript
Node.js对MongoDB数据库实现模糊查询的方法
2017/05/03 Javascript
layer.open关闭父窗口 以及调用父页面的方法
2018/08/17 Javascript
JS实现数组深拷贝的方法分析
2019/03/06 Javascript
Javascript模块化机制实现原理详解
2020/04/02 Javascript
详解Vue的mixin策略
2020/11/19 Vue.js
Python类的专用方法实例分析
2015/01/09 Python
Python的Flask框架中实现登录用户的个人资料和头像的教程
2015/04/20 Python
python读取word文档的方法
2015/05/09 Python
Python多线程经典问题之乘客做公交车算法实例
2017/03/22 Python
Python模拟鼠标点击实现方法(将通过实例自动化模拟在360浏览器中自动搜索python)
2017/08/23 Python
用十张图详解TensorFlow数据读取机制(附代码)
2018/02/06 Python
pandas数据清洗,排序,索引设置,数据选取方法
2018/05/18 Python
HTML5引入的新数组TypedArray介绍
2012/12/24 HTML / CSS
2013年学期结束动员演讲稿
2014/01/07 职场文书
教育科研先进个人材料
2014/01/26 职场文书
公司活动方案范文
2014/03/06 职场文书
银行客户经理培训心得体会
2016/01/09 职场文书
使用HTML+Css+transform实现3D导航栏的示例代码
2021/03/31 HTML / CSS
Pytorch中TensorBoard及torchsummary的使用详解
2021/05/12 Python