redux-simple 简化版的redux

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

使用实例如下:

 1 import React from "react";
 2 import ReactDOM from "react-dom";
 3 import Component,{connect} from "./react-simple.js";
 4 class Test01 extends Component{
 5     constructor(props){
 6         super(props);
 7         this.props.listenProps(["test01"],this)
 8     }
 9     render() {
10         console.log(this.props.test01);
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.dispatch({
21             test01:789,
22         })
23     }
24     render() {
25         console.log(this.props.test02);
26         return <h1 onClick={this.clickHandler.bind(this)}>{this.props.test02}</h1>;
27     }
28 }
29 class Main extends Component{
30     componentDidMount(){
31         this.props.dispatch({
32             test01:123,
33             test02:456,
34         })
35     }
36     render() {
37         return <div>
38             <Test01 {...this.props}/>
39             <Test02 {...this.props} />
40         </div>;
41     }
42 }
43 var NewCom=connect(Main);
44 ReactDOM.render(
45     <NewCom />,
46     document.getElementById("container")
47 )
时间: 2024-10-18 06:49:35

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

redux源码解析-redux的架构

redux很小的一个框架,是从flux演变过来的,尽管只有775行,但是它的功能很重要.react要应用于生成环境必须要用flux或者redux,redux是flux的进化产物,优于flux. 而且redux还很小.那么redux是怎么做到单项数据流和一些让人惊奇的特性的呢.我们来看一下他的源码,从而学一些东西. redux里面都是一个一个的模块,一共9个模块,都导出了一些redux的方法,比如这个9,一个匿名函数,然后导出他写的方法.9里面就这一个方法.英文注释也蛮清楚的,检测类对象的方法.

Unity - UIWidgets 7. Redux接入(二) 把Redux划分为不同数据模块

参考QF.UIWidgets 参考Unity官方示例 - ConnectAppCN 前面说过,当时没想明白一个问题,在reducer中每次返回一个new State(), 会造成极大浪费,没想到用什么办法来解决. 然后发现这些示例里面并没有每次创建一个新的State,只是直接修改了相应的值--那这样就简单多了.把Redux结构划分为不同数据模块,更方面管理. 在这里从头做一个简单的demo,包含两个页面:"homepage",显示一条信息, "newpage",显示

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

1. src 下的 common 下的 header 创建 store 文件夹 下创建 reducer.js # src/common/header/store/reducer.js const stateDefault = { focused : false }; export default (state = stateDefault, action)=>{ if(action.type === 'focus' || action.type === 'blur'){ const newSta

redux源码解析,函数式编程

提到redux,会想到函数式编程.什么是函数式编程?是一种很奇妙的函数式的编程方法.你会感觉函数式编程这么简单,但是用起来却很方便很神奇. 在<functional javascript>中,作者批评了java那种任何东西都用对象来写程序的方式,提倡了这种函数式编程. 之前看过一些函数式编程的例子(以下简称fp).提到fp会想到underscore和lodash,你会看到lodash的包中,唯一一个文件夹就是fp,里面是fp相关的函数. 在redux中,也是运用了很多fp的函数.其实在写js中

理解Javascript的状态容器Redux

Redux要解决什么问题? 随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (状态). 这些 state 可能包括服务器响应.缓存数据.本地生成尚未持久化到服务器的数据,也包括 UI 状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等.管理不断变化的 state 非常困难.如果一个 model 的变化会引起另一个 model 变化,那么当 view 变化时,就可能引起对应 model 以及另一个 model 的变化,依

数据流程redux

思考题: react+redux开发这么一个原型,要怎么开发? 整个redux流程的逻辑非常清晰,数据流是单向循环的,就像一个生产的流水线: store(存放状态) -> Container(显示状态) -> reducer (处理动作)-> store redux画图理解: redux 只是定义了应用的数据流程,只解决了 "数据层"(model layer) 的问题, 一般还会使用 react, angular 等作为"显示层" (UI laye

Flux --&gt; Redux --&gt; Redux React 入门 基础实例使用

本文的目的很简单,介绍Redux相关概念用法 及其在React项目中的基本使用 假设你会一些ES6.会一些React.有看过Redux相关的文章,这篇入门小文应该能帮助你理一下相关的知识 一般来说,推荐使用 ES6+React+Webpack 的开发模式,但Webpack需要配置一些东西,你可以先略过,本文不需要Webpack基础 入门,只是一些基础概念和用法的整理,更完整的内容推荐去看看文档,英文,中文 (不过我个人认为,官方文档的例子相对来说太复杂了,很难让新手马上抓住重点) (官方的例子正

Redux生态系统

生态系统 Redux 是一个体小精悍的库,但它相关的内容和 API 都是精挑细选的,足以衍生出丰富的工具集和可扩展的生态系统. 如果需要关于 Redux 所有内容的列表,推荐移步至 Awesome Redux.它包含了示例.样板代码.中间件.工具库,还有很多其它相关内容.要想学习 React 和 Redux ,React/Redux Links 包含了教程和不少有用的资源,Redux Ecosystem Links 则列出了 许多 Redux 相关的库及插件. 本页将只列出由 Redux 维护者

ES6+redux实现Counter

react说白了就是用jsx开发一个view层的东西,如果你要想开发一些web端的网页应用,你需要做的就是结合起目前可以管理数据端的一些应用,今天我们说到的是redux,redux我目前学习的也不是很深,前后差不多10天时间,只谈一下自己的理解! 网络上有很多关于redux的讲解,目前觉得阮一峰大神的最适合入门者初学,http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html redux是通过什