在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 相关文章推荐
使用jQuery实现dropdownlist的联动效果(sharepoint 2007)
Mar 30 Javascript
JS辨别访问浏览器判断是android还是ios系统
Aug 19 Javascript
JavaScript判断文件上传类型的方法
Sep 02 Javascript
jQuery选择器及jquery案例详解(必看)
May 20 Javascript
jQuery增加和删除表格项目及实现表格项目排序的方法
May 30 Javascript
基于SpringMVC+Bootstrap+DataTables实现表格服务端分页、模糊查询
Oct 30 Javascript
使用AngularJS2中的指令实现按钮的切换效果
Mar 27 Javascript
jQuery each和js forEach用法比较
Feb 27 jQuery
Vue使用NProgress进度条的方法
Sep 21 Javascript
vue项目中使用vue-layer弹框插件的方法
Mar 11 Javascript
使用konva和vue-konva库实现拖拽滑块验证功能
Apr 27 Javascript
谈谈JavaScript中的垃圾回收机制
Sep 17 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
剧场版动画《PSYCHO-PASS 3 FIRST INSPECTOR》3月27日日本上映!
2020/03/06 日漫
PHP 彩色文字实现代码
2009/06/29 PHP
基于asp+ajax和数据库驱动的二级联动菜单
2010/05/06 PHP
php类中private属性继承问题分析
2012/11/01 PHP
在Nginx上部署ThinkPHP项目教程
2015/02/02 PHP
php intval函数用法总结
2019/04/14 PHP
JavaScript this 深入理解
2009/07/30 Javascript
EXTJS内使用ACTIVEX控件引起崩溃问题的解决方法
2010/03/31 Javascript
7个有用的jQuery代码片段分享
2015/05/19 Javascript
JS实现双击屏幕滚动效果代码
2015/10/28 Javascript
超精准的javascript验证身份证号的具体实现方法
2015/11/18 Javascript
javascript实现网页中涉及的简易运动(改变宽高、透明度、位置)
2015/11/29 Javascript
node+express制作爬虫教程
2016/11/11 Javascript
js实现瀑布流效果(自动生成新的内容)
2017/03/16 Javascript
Bootstrap table使用方法记录
2017/08/23 Javascript
详解js几个绕不开的事件兼容写法
2017/08/30 Javascript
vue.js使用代理和使用Nginx来解决跨域的问题
2018/02/03 Javascript
ndm:NPM的桌面GUI应用程序
2018/10/15 Javascript
vue中的mescroll搜索运用及各种填坑处理
2019/10/30 Javascript
Taro UI框架开发小程序实现左滑喜欢右滑不喜欢效果的示例代码
2020/05/18 Javascript
[04:13]2014DOTA2国际邀请赛 专访DC目前形势不容乐观
2014/07/12 DOTA
[52:06]FNATIC vs NIP 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
使用wxPython获取系统剪贴板中的数据的教程
2015/05/06 Python
Windows下实现Python2和Python3两个版共存的方法
2015/06/12 Python
python中文件变化监控示例(watchdog)
2017/10/16 Python
python实现拼接图片
2020/03/23 Python
css3中less实现文字长阴影(long shadow)
2020/04/24 HTML / CSS
波兰运动鞋网上商店:e-Sporting
2018/02/16 全球购物
经济与贸易专业应届生求职信
2013/11/19 职场文书
党的群众路线教育实践活动对照检查材料
2014/09/22 职场文书
学位证书委托书
2014/09/30 职场文书
2014年校务公开工作总结
2014/12/18 职场文书
个人总结怎么写
2015/02/26 职场文书
工作态度恶劣检讨书
2015/05/06 职场文书
微信早安问候语
2015/11/10 职场文书
HTML基础-标签分类(闭合标签,空标签,块级元素,行内元素,行级块元素,可替换元素)
2021/03/31 HTML / CSS