在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 相关文章推荐
Javascript实例教程(19) 使用HoTMetal(6)
Dec 23 Javascript
原生的html元素选择器类似jquery选择器
Oct 15 Javascript
angularjs 处理多个异步请求方法汇总
Jan 06 Javascript
javascript 兼容各个浏览器的事件
Feb 04 Javascript
js添加绑定事件的方法
May 15 Javascript
AngularJS入门教程之迭代器过滤详解
Aug 18 Javascript
jQuery无缝轮播图代码
Dec 22 Javascript
jquery.picsign图片标注组件实例详解
Feb 02 jQuery
jQuery实现的点击按钮改变样式功能示例
Jul 21 jQuery
JavaScript根据json生成html表格的示例代码
Oct 24 Javascript
Vue使用JSEncrypt实现rsa加密及挂载方法
Feb 07 Javascript
jQuery实现简易QQ聊天框
Feb 10 jQuery
使用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
php5.2时间相差8小时
2007/01/15 PHP
php cli换行示例
2014/04/22 PHP
Win2003+apache+PHP+SqlServer2008 配置生产环境
2014/07/29 PHP
PHP实现XML与数据格式进行转换类实例
2015/07/29 PHP
PHP实现长文章分页实例代码(附源码)
2016/02/03 PHP
javascript之可拖动的iframe效果代码
2008/08/01 Javascript
用jquery实现点击栏目背景色改变
2012/12/10 Javascript
Extjs根据条件设置表格某行背景色示例
2014/07/23 Javascript
EasyUI,点击开启编辑框,并且编辑框获得焦点的方法
2015/03/01 Javascript
js实现继承的5种方式
2015/12/01 Javascript
利用jQuery的动画函数animate实现豌豆发射效果
2016/08/28 Javascript
vue实现ajax滚动下拉加载,同时具有loading效果(推荐)
2017/01/11 Javascript
深入理解vue-loader如何使用
2017/06/06 Javascript
AngularJS中filter的使用实例详解
2017/08/25 Javascript
基于vue配置axios的方法步骤
2017/11/09 Javascript
jquery实现侧边栏左右伸缩效果的示例
2017/12/19 jQuery
js/jquery遍历对象和数组的方法分析【forEach,map与each方法】
2019/02/27 jQuery
微信小程序动态添加view组件的实例代码
2019/05/23 Javascript
Vue 3.0 前瞻Vue Function API新特性体验
2019/08/12 Javascript
Vue 中使用lodash对事件进行防抖和节流操作
2020/07/26 Javascript
简介Python中用于处理字符串的center()方法
2015/05/18 Python
python中比较两个列表的实例方法
2019/07/04 Python
对django layer弹窗组件的使用详解
2019/08/31 Python
关于HTML5你必须知道的28个新特性,新技巧以及新技术
2012/05/28 HTML / CSS
HTML5的语法变化介绍
2013/08/13 HTML / CSS
个人求职自荐信范文
2014/06/20 职场文书
中国梦团日活动总结
2014/07/07 职场文书
项目合作意向书模板
2014/07/29 职场文书
2014四风问题对照检查材料范文
2014/09/15 职场文书
党的群众路线教育实践活动个人对照检查材料(企业)
2014/11/05 职场文书
项目投资意向书范本
2015/05/09 职场文书
2016年师德师风学习心得体会
2016/01/12 职场文书
关于公司年会的开幕词
2016/03/04 职场文书
使用这 6个Vue加载动画库来减少我们网站的跳出率
2021/05/18 Vue.js
超详细教你怎么升级Mysql的版本
2021/05/19 MySQL
解决persistence.xml配置文件修改存放路径的问题
2022/02/24 Java/Android