在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 相关文章推荐
客户端脚本中常常出现的一些问题和调试技巧
Jan 09 Javascript
javascript页面加载完执行事件代码
Feb 11 Javascript
jQuery学习笔记之 Ajax操作篇(二) - 数据传递
Jun 23 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
Sep 04 Javascript
简介JavaScript中的setDate()方法的使用
Jun 11 Javascript
AngularJS ng-bind 指令简单实现
Jul 30 Javascript
Bootstrap基本插件学习笔记之按钮(21)
Dec 08 Javascript
Node.js的特点详解
Feb 03 Javascript
JS仿淘宝搜索框用户输入事件的实现
Jun 19 Javascript
最全正则表达式总结:验证QQ号、手机号、Email、中文、邮编、身份证、IP地址等
Aug 16 Javascript
angular学习之动态创建表单的方法
Dec 07 Javascript
vue引入微信sdk 实现分享朋友圈获取地理位置功能
Jul 04 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 图像尺寸调整代码
2010/05/26 PHP
Trying to clone an uncloneable object of class Imagic的解决方法
2012/01/11 PHP
如何利用PHP执行.SQL文件
2013/07/05 PHP
php上传图片之时间戳命名(保存路径)
2014/08/15 PHP
PHP实现找出链表中环的入口节点
2018/01/16 PHP
php面向对象程序设计入门教程
2019/06/22 PHP
自动生成文章摘要的代码[JavaScript 版本]
2007/03/20 Javascript
jquery.validate使用攻略 第五步 正则验证
2010/07/01 Javascript
图片动画横条广告带上下滚动可自定义图片、链接等等
2013/10/20 Javascript
Jquery实现自定义弹窗示例
2014/03/12 Javascript
用javascript实现自动输出网页文本
2015/07/30 Javascript
常用原生JS兼容性写法汇总
2016/04/27 Javascript
jQuery实现立体式数字滚动条增加效果
2016/12/21 Javascript
Bootstrap 模态对话框只加载一次 remote 数据的完美解决办法
2017/07/09 Javascript
JS交互点击WKWebView中的图片实现预览效果
2018/01/05 Javascript
vue-router项目实战总结篇
2018/02/11 Javascript
Vue2.0仿饿了么webapp单页面应用详细步骤
2018/07/08 Javascript
Vue实现根据hash高亮选项卡
2019/05/27 Javascript
创建nuxt.js项目流程图解
2020/03/13 Javascript
vue路由结构可设一层方便动态添加路由操作
2020/08/31 Javascript
vant 解决tab切换插件标题样式自定义的问题
2020/11/13 Javascript
Python OS模块常用函数说明
2015/05/23 Python
Python采用Django开发自己的博客系统
2020/09/29 Python
Python关于excel和shp的使用在matplotlib
2019/01/03 Python
Python基础之变量基本用法与进阶详解
2020/01/03 Python
基于OpenCV的路面质量检测的实现
2020/11/04 Python
python 检测nginx服务邮件报警的脚本
2020/12/31 Python
Blue Nile台湾:钻石珠宝商,订婚首饰、结婚戒指和精品首饰
2017/11/24 全球购物
社区十八大感言
2014/01/19 职场文书
校园联欢晚会主持词
2014/03/17 职场文书
假面舞会策划方案
2014/05/29 职场文书
学校献爱心活动总结
2014/07/08 职场文书
2014年学校食堂工作总结
2014/11/25 职场文书
检讨书大全
2015/01/27 职场文书
Nginx+SpringBoot实现负载均衡的示例
2021/03/31 Servers
MySQL GRANT用户授权的实现
2021/06/18 MySQL