• redux源码解读(二)


    之前,已经写过一篇redux源码解读(一),主要分析了 redux 的核心思想,并用100多行代码实现一个简单的 redux 。但是,那个实现还不具备合并 reducer 和添加 middleware 的功能。

    今天我们一起来看看合并 reducer (即 combineReducers) 的原理和实现。

    在分析原理之前,先来看看combineReducers 的用法:

    import { createStore, combineReducers } from 'redux';
    const addScore = (state, action) => {};
    const deleteScore = (state, action) => {};
    const rootReducer = combineReducers({addStore, deleteScore});
    const store = createStore(rootReducer);
    

    从上面的例子可以看出,combineReducers 接收的参数类型是一个原生对象,其中这个对象的每个键值都是一个 reducer 纯函数。另外,因为 combineReducer() 返回的结果可以传递给createStore作为参数,可以推出它返回的结果也是一个 reducer 函数。

    了解了 combineReducer 用法之后 ,那开始一步一步的用代码来实现其功能吧。

    首先,需要先声明 combineReducers 的参数,然后判断传进来的参数是不是原生对象类型( plain object ),如果不是,则抛出异常,如果是,则需要获取该对象的所有属性(key)并存放到变量 reducerKeys 里面,然后对这些key进行遍历,过滤掉那些不是函数的值,并将结果放到 finalReducerKeys 里面。代码如下:

    export default function combineReducers(reducers) {
      // 判断参数reducers是否为对象
      if(Object.prototype.toString.call(reducer) !== '[object Object]') {
        throw new Error('combineReducers expected plain object params');
      }
    
      const reducerKeys = Object.keys(reducers);
      let finalReducerKeys = [];
      // 过滤掉value不是Function类型的键名,然后将结果放到fianlReducerKeys里面
      reducerKeys.forEach((key, i) => {
        if(typeof reducers[key] === 'function') {
          finalReducerKeys.push(key);
        }
      });
    }
    

    前面已经提到过了 combineReducers 返回的结果是一个纯函数。那这个返回的函数需要处理些什么逻辑呢?因为他合并了其他的 reducers,所以需要遍历这些 reducer 并执行他们。然后,并对比一下执行 reducer 之后的数据有没有变化 ,如果有变化则返回新的 state , 否则直接返回之前的 state。代码如下:

    export default function combineReducers(reducers) {
      // 省略和前面相同的部分
    
      // 返回一个新的、经过组合的reducer函数
      return function(state = {}, action) {
        let hasChanged = false;
        const nextState = {};
        // 遍历finalReducerKeys,并调用对应的reducer。
        finalReducerKeys.forEach((key, i) => {
          const stateForKey = state[key];
          const nextStateForKey = reducers[key](stateForKey, action);
          nextState[key] = nextStateForKey;
          // 如果前后状态不一样,则hasChanged设为true
          if(stateForKey !== nextStateForKey) {
            hasChanged = true;
          }
        });
        // 如果有变化,则返回新的state,否则返回旧的
        return hasChanged ? nextState : state;
      }
    }
    

    OK,《redux 源码解读(二)》就写到这里,今天周五啦,祝大家周末愉快哈!如果对 combineReducer还有不明白的地方,欢迎留言讨论哈。另外,可能有些地方我分析得不到位的,建议到我的github去下载代码自己再好好研究一下。重要的事情说三遍:代码在这里下载! 代码在这里下载! 代码在这里下载!

  • 相关阅读:
    深入理解系统调用
    基于mykernel 2.0编写一个操作系统内核
    交互式多媒体图书平台的设计与实现
    Ubuntu下VSCode调试环境搭建指南-C语言篇
    码农的自我修养之必备技能 学习笔记
    工程化编程实战callback接口学习笔记
    CentOS7.4网络配置
    R-CNN
    CUDA整理
    CUDA by Example 第四章 julia集
  • 原文地址:https://www.cnblogs.com/yugege/p/9416059.html
Copyright © 2020-2023  润新知