对于 redux 的一些理解-1.基础

最近从 https://github.com/frontend9 上看了下博主对 redux 学习过程的一个分享 , 讲解的很是仔细易懂 , 感兴趣的建议从博主的 https://github.com/brickspert/blog/issues/22 案例中去逐个学习理解(动手敲) , 相信必定可以对 redux的使用有个完全的理解;html

 

咱们从中文文档中能够看到这样的话:git

 

'随着 JavaScript 单页应用开发日趋复杂,JavaScript 须要管理比任什么时候候都要多的 state (状态)。 这些 state 可能包括服务器响应、缓存数据、本地生成还没有持久化到服务器的数据,也包括 UI 状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等'github

Redux 试图让 state 的变化变得可预测。这些限制条件反映在了 redux 的三大原则中ajax

1:单一数据源redux

2:state 是只读的缓存

3:使用纯函数来执行修改服务器

 

假设你历来没有用过 redux, 抛弃这些名词, 回到原始的开发模式。使用 ajax 从服务器请求数据, 根据数据生成 html片断, 插入到指定的 dom节点。逻辑很简单根本就不须要使用框架, 就能够得到很好的开发和浏览体验。框架

当单页面模式推崇以后 , 全部的操做都在一个 html文件中去处理, 状况变得复杂起来了。在一个页面中你须要处理各个模块的逻辑 , 你要不断去处理数据的更新, 添加, 删除; 这时候若是不对数据修改加以约束(随处可见的修改, 跨页面的修改等), 会难以追踪到你的数据走向。frontend

尤为是对于引用类型数据, 对某一处不经意的修改, 简直会让人崩溃(你不知道到底在哪里做了修改, 可能就发生在某一个函数的调用中, 好比对形参 param.a = 1 这种操做)。dom

这时候也有人推出了深复制的解决办法, 每次都是操做一个全新的对象, 对源数据不会形成任何影响, 思路固然没错. 可这距离咱们指望的结果: 对于数据的每一次修改都是可监测可控制的。仍是有些差距。

 

Redux 的推出可谓是一种很好的解决方案。正如 redux文档自述中所言: Redux 是 JavaScript 状态容器,提供可预测化的状态管理

正由于它坚持的三大原则

1. 单一数据源; 避免了咱们在各个模块中去重复复制, 重复定义, 这对于整个应用的数据更新都会带来麻烦; 要么只在模块内部去定义, 要么定义在全局(单一数据源上), 不推荐在内部定义一个, 在全局又定义一个同一用途的数据;

2. state 是只读的, redux提供了惟一改变 state 的方法就是触发 action; 它们只能表达想要修改的意图,

3. 使用纯函数来执行修改;

  咱们来看一看执行修改的逻辑就明白了:

function changeCount(state={}, action){
    switch(action.type) {
        case 'INCREMENT':
            return {
                ...state,
                count: state.count + 1
            }
        default:
            return state
    }   
}

咱们对原状态 state 没有作任何修改, 只是返回了一个新的 state; 借由此, 在处理逻辑时, 咱们能够把应用上一次的 state, 和更新后的 state 都传递出去; 甚至咱们能够改写里面的逻辑, 记录下前几回状态值的修改;

始终记住 redux提供可预测化的状态管理, 这就是它所作的工做。

 

 

/***********************    *************************************/

在之前本身去记录应用状态的作法多是这样的;

function createStore (initData) {
    var APP_DATA = initData || {};

return { get: function (key) { return key ? APP_DATA[key] : APP_DATA; }, set: function (key, data) { APP_DATA[key] = data; } } } var Store = createStore(); function getUserInfo () { setTimeout(function () { var userInfo = { name: '张三', age: '23' }; Store.set('userInfo', userInfo); }, 100) } getUserInfo(); function validate () { return !!Store.get('userInfo'); } function submit () { var userInfo; if (validate()) { userInfo = Store.get('userInfo'); console.log(userInfo); } } setTimeout(submit, 300);

 

换做用 redux 可能得这样

function createStore (reducer, initState) {
    var listeners = [];
    var store = initState;
    
    function getState () {
        return store;
    }
    
    function subscribe (listen) {
        listeners.push(listen)
    }
    
    function dispatch (action) {
        store = reducer(store, action);
        for(var i = 0; i < listeners.length; i++) {
            listeners[i]()
        }
    }
    
    return {
        getState: getState,
        subscribe: subscribe,
        dispatch: dispatch
    }
}

function reducer (state, action) {
    switch (action.type) {
        case 'SET_USERINFO':
            return {
                ...state,
                userInfo: action.data
            }
        default:
            return state;
    }
}

var Store = createStore(reducer, {});

function getUserInfo () {
    setTimeout(function () {
        Store.dispatch({
            type: 'SET_USERINFO',
            data: { name: '张三', age: '23' }
        });
    }, 100)
}
getUserInfo();

function validate () {
    return !!Store.getState().userInfo;
}

function submit () {
    var userInfo;
    if (validate()) {
        userInfo = Store.getState().userInfo;
        
        console.log(userInfo);
    }
}

setTimeout(submit, 300);

应该用什么样的方式去管理应用状态 , 这个问题或许太宽泛没法回答 , 我只能说踩过的一些坑 , 也是对以前的"错误作法"一些总结:

1. 赋值操做时要格外当心 , 尤为是引用; 

2. 避免兀余的数据 , 这时咱们经常会定义些 "全局变量" , 来保存多个位置的相同信息。尽可能去约束修改的行为

3. 保护好你的应用数据 。不得已 能够经过重置的手段还原到初始状态。

 

 

/***********************  补充  *************************************/

对于 redux 本身也存在些疑惑的地方 , 在下面暂且把它视做 redux 的缺陷吧

1. redux 的 action 分发机制: 在源码中 action 被自顶往下层层传递 , 也就意味全部的下级状态都会接受到消息 , 那也就可能存在 有多个下级状态 同时作出响应 ---- 只要 action.type 不是惟一, 那么就必然会出现这种状况

  这一点能够被利用来作一些特定场景 , 但糟糕的设想是: 一个应用中有 未知数相同的 action.type, 在某一处的修改触发了全部状态的修改 ;

  理想情况下 , 咱们应该只修改当前状态的值 , 而不该扩宽它的影响范围 , 所以称它为缺陷。 咱们在开发中应该尽可能对 action.type 命名惟一。

 

始终记住 redux提供可预测化的状态管理。目前它并不完美 , 但足够优秀。