作为react的粉丝,当然要吐槽一下react组件通信问题。react的单向数据流是组件通信的一大阻碍,只允许父组件向子组件传值,子组件向父组件传值只能通过父组件向子组件传递回调函数实现。如果在深层次的组件结构当中,复杂与繁多的回调会大大增加程序的维护难度与可读性,延长开发周期。即使react实现的再优秀,组件通信没处理好,还是一坨屎。redux给react的组件通信带来解决方案:构建一个大的状态作用域(一个大组件),大组件里的所有组件状态变化都只需要维护大组件,更新的状态都有大组件开始下发,这样就避免了子组件向父组件传值需要回调方法的问题。

redux优点:贯彻了react的单向数据流思想,避免父子组件通信时繁琐的回调,清晰的数据流简化了业务逻辑实现,提高应用维护效率。

redux槽点:为了数据中心化与自动化测试分离出了action与redcuer与mapStateToProps,简单的数据操作被复杂化了。每次dispatch都会重新渲染状态作用域里的所有组件,虽然react使用diff算法筛选出需要改变的节点进行渲染(优化了性能),但是在庞大以及深层次的组件结构中,diff带来的消耗还是不可忽视的。

  我格外厌恶redux繁琐的操作,所以自己实现了一个简化版的redux。把action与redcuer合并、废弃了mapStateToProps简化了redux的数据操作。由于action与redcuer的合并后存在数据依赖,所以合并后的action不能做数据自动化测试。除了简化redux的繁琐的数据操作之外,还通过监听组件里的动态数据与dispatch更新的数据对比检测该组件是否需要重新渲染,解决redux最大的弊端【redux组件渲染弊端:redux dispatch后没有变化的组件也会被重新渲染,这是不必要的性能消耗】。我还丰富了Component基类给每个组件提供了重新渲染检测功能。

redux-simple.s实现如下:

  1. import React,{Component,createElement} from "react";
  2. var event=function(){
  3. var propsment={};
  4. var dispatchProps={};
  5. return {
  6. //添加监听属性
  7. listenProps:function(props,_this){
  8. if(_this.constructor&&_this.constructor.name){
  9. propsment[_this.constructor.name]=props;
  10. }else{
  11. throw new Error("监听对象不是react组件");
  12. }
  13. },
  14. //清空监听的属性
  15. emptyProps:function(){
  16. propsment={};
  17. },
  18. //检测是否需要更新
  19. checkProps:function(_this){
  20. var data=propsment[_this._reactInternalInstance.getName()]||[];
  21. var propKeys=Object.keys(dispatchProps);
  22. //没有监听属性的组件直接更新
  23. if(!data.length){
  24. return true;
  25. }
  26. for(var i=0;i<data.length;i++){
  27. //判断监听的属性是否存在于更新数据里面,存在则更新组件
  28. if(propKeys.indexOf(data[i])!=-1){
  29. return true;
  30. }
  31. }
  32. return false;
  33. },
  34. //监听更新的数据
  35. listenDispatch:function(props){
  36. dispatchProps=props;
  37. }
  38. }
  39.  
  40. }()
  41. export function connect(App,actions){
  42. let dispatch,getState;
  43. dispatch=getState=function(){
  44. throw new Error("组件还没初始化");
  45. }
  46. class Main extends Component{
  47. constructor(props){
  48. super(props);
  49. this.constructor.setState=dispatch=(data)=>{
  50. //监听更新的数据
  51. event.listenDispatch(data);
  52. //更新store
  53. this.setState(Object.assign({},this.state,data));
  54. }
  55. getState=()=>{
  56. return Object.assign({},this.state);
  57. }
  58. this.actions=bindAction(actions,dispatch,getState||{});
  59. }
  60. render(){
  61. return <div>
  62. {createElement(App,Object.assign({dispatch:dispatch,listenProps:event.listenProps,getState:getState,actions:this.actions},this.props,this.state))}
  63. </div>
  64. }
  65. }
  66. return Main;
  67. }
  68. //action方法绑定dispatch并支持异步
  69. function bindActionCreators(action,dispatch,getState){
  70. if(typeof action==="function"){
  71. return function(){
  72. [].unshift.call(arguments,getState());
  73. var newState=action.apply(null,arguments);
  74. if(typeof newState==="function"){
  75. newState(dispatch)
  76. }else if(isObject(newState)){
  77. dispatch(newState);
  78. }else{
  79. throw new Error("action方法返回值只能是函数或者对象");
  80. }
  81. }
  82. }
  83. }
  84. //给所有的action方法绑定dispatch
  85. export function bindAction(actions,dispatch,getState){
  86. var newActions={};
  87. if(isObject(actions)){
  88. var keys=Object.keys(actions);
  89. keys.forEach(function(value){
  90. newActions[value]=bindActionCreators(actions[value],dispatch,getState)
  91. })
  92. return newActions;
  93. }else if(actions){
  94. throw new Error("actions必须是对象")
  95. }
  96. }
  97. //检测是否是一个对象
  98. let isObject=(data)=>{
  99. if(Object.prototype.toString.call(data)=="[object Object]"){
  100. return true;
  101. }else{
  102. return false;
  103. }
  104. }
  105. //构建新的组件基类
  106. export default class NewCom extends Component{
  107. shouldComponentUpdate(nextProps){
  108. return event.checkProps(this,nextProps); //检测是否重新渲染该组件
  109. }
  110. componentWillUnmount(){
  111. event.emptyrProps(); //清空监听列表
  112. }
  113. }

使用实例如下:

  

  1. import ReactDom from "react-dom";
  2. import React from "react";
  3. import Component,{connect} from "./react-extend.js";
  4. import * as actions from "./action/test.js";
  5. class Test01 extends Component{
  6. constructor(props){
  7. super(props);
  8. this.props.listenProps(["test01"],this); //监听该组件的动态数据
  9. }
  10. render(){
  11. return <h1>{this.props.test01}</h1>
  12. }
  13. }
  14. class Test02 extends Component{
  15. constructor(props){
  16. super(props);
  17. this.props.listenProps(["test02"],this); //监听该组件的动态数据
  18. }
  19. clickHandler(){
  20. this.props.actions.changeTest01(789);
  21. }
  22. render(){
  23. return <h1 onClick={this.clickHandler.bind(this)}>{this.props.test02}</h1>
  24. }
  25. }
  26. class Main extends Component{
  27. componentDidMount(){
  28. this.props.actions.init({
  29. test01:123,
  30. test02:456,
  31. })
  32. }
  33. render(){
  34. return <div>
  35. <Test01 {...this.props}/>
  36. <Test02 {...this.props}/>
  37. </div>
  38. }
  39. }
  40. var NewMain=connect(Main,actions);
  41. ReactDom.render(
  42. <NewMain />,
  43. document.getElementById("container")
  44. )

action:

  1. export function changeTest01(state,value){
  2. return {
  3. test01:value,
  4. }
  5. }
  6. export function init(state,obj){
  7. return obj;
  8. }

redux-simple 简化版的redux的更多相关文章

  1. redux源码解析-redux的架构

    redux很小的一个框架,是从flux演变过来的,尽管只有775行,但是它的功能很重要.react要应用于生成环境必须要用flux或者redux,redux是flux的进化产物,优于flux. 而且r ...

  2. react第十六单元(redux的认识,redux相关api的掌握)

    第十六单元(redux的认识,redux相关api的掌握) #课程目标 掌握组件化框架实现组件之间传参的几种方式,并了解两个没有任何关系组件之间通信的通点 了解为了解决上述通点诞生的flux架构 了解 ...

  3. [Redux + Webpack] Hot reloading Redux Reducers with Webpack

    Webpack will hot reload the component, but the reducer we need hard refresh. To sovle the problem, g ...

  4. Redux学习笔记:Redux简易开发步骤

    该文章不介绍Redux基础,也不解释各种乱乱的概念,网上一搜一大堆.只讲使用Redux开发一个功能的步骤,希望可以类我的小白们,拜托它众多概念的毒害,大牛请绕道! 本文实例源代码参考:React-Re ...

  5. redux sample with slim redux source code

    code sample没有package.json文件,也就没有任何外部依赖,直接使用slim redux source code. slim resux只有90多行. nodejs对es6的impo ...

  6. [Redux] Important things in Redux

    Root Smart component can be overloaded, divide 'smart' component wisely & using Provider. Proble ...

  7. 1.Redux学习1,Redux

    Redux流程图如上: Action就是一条命令 Store顾名思义就是存储数据的, Reducers是一个回调函数用于处理数据,它处理完数据会返回给Store存储起来 基本流程就是:组件中用Stor ...

  8. 4 react 简书 引入 redux 的 combineReducers 对 redux 数据进行管理

    1. src 下的 common 下的 header 创建 store 文件夹 下创建 reducer.js # src/common/header/store/reducer.js const st ...

  9. React之redux学习日志(redux/react-redux/redux-saga)

    redux官方中文文档:https://www.redux.org.cn/docs/introduction/CoreConcepts.html react-redux Dome:https://co ...

随机推荐

  1. Kafka笔记--指定消息的partition规则

    参数的设定:参考资料 不错的资料:http://blog.csdn.net/honglei915/article/details/37697655 http://developer.51cto.com ...

  2. 浏览器的模式问题 Quirks Mode vs Standards Mode

    当微软开始产生与标准兼容的浏览器时,他们希望确保向后兼容性.为了实现这一点,他们IE6.0以后的版本在浏览器内嵌了两种表现模式: Standards Mode(标准模式或Strict Mode)和Qu ...

  3. 使用JQUERY实现局部页面定时刷新

    没办法,运维会一点点前端,还是有好处的.. 说不定,BOOTSTRAP也得会一点点.. 本想用流式输出的搞定的,但没搞定,就取巧了... 代理简单: <script src="//cd ...

  4. 一张图看懂片式多层陶瓷电容器(MLCC)

  5. DC-DC转换器原理与应用

    DC/DC转换器为转变输入电压后,有效输出固定电压的电压转换器.DC/DC转换器分为三类:升压型DC/DC转换器.降压型DC/DC转换器以及升降压型DC/DC转换器.根据需求可采用三类控制.PWM控制 ...

  6. Codec plugins ? multiline

    Codec plugins ? multiline multiline codec 会折叠多行消息,合并它们到一个事件 这个codec 原始的目的是允许 连接多行信息从文件到一个单独的事件. 比如, ...

  7. 深入JS系列学习2

    今天看和学习了深入理解JS系列2.3.4.5,更加明白了函数声明和表达式的区别,自执行函数和立即执行函数,js强大的原型链继承,js中对象的想过写法,modules模式等. 在ECMAScript中, ...

  8. vs 2013调试的时候重启的解决方案

    今天在用vs 2013 调试程序的时候,vs 总是莫名其妙的关闭,停止运行,泪蹦了..... 是什么原因呢? 以前的时候可是好好的啊,经过认真的思索,最近装过和vs 2013 相关的程序也只有 ref ...

  9. Java的多线程(上)

    多线程的优点和必要性是不言而喻的. 三种方法实现多线程 1. 继承Thread class A extends Thread{ public void run() {...} } 使用时, new A ...

  10. Confluence简介

    前言     我们有很多的知识共享的工具,比如我们每天都用的qq共享,网盘共享,但是都不如我们这个来的方便,直接.这个是直接通过网页的形式进行共享,类似于我们的博客共享,但是它更加的具有指向性,站点管 ...