继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

redux源码解读(二)

炎炎设计
关注TA
已关注
手记 333
粉丝 74
获赞 371

之前,已经写过一篇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去下载代码自己再好好研究一下。重要的事情说三遍:代码在这里下载! 代码在这里下载! 代码在这里下载!

原文出处:https://www.cnblogs.com/yugege/p/9416059.html

打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP