Redux中的Reducers

  Redux中的action只是表明了在应用中发生了什么,但是并没有对数据state进行处理,Reducers就是用来处理数据的。
  因为在Redux中只有一个state对象,所以在设计state时我们要尽量将我们必须的数据保存在state中。

Reducers是如何处理action的

下面我们以具体示例来看下reducer是如何在接收到action对数据进行处理的。
function todoApp(state = initialState, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return Object.assign({}, state, {
        visibilityFilter: action.filter
      })
    default:
      return state
  }
}

  其中todoApp就是我们定义的Reducers,它接收两个参数:当前state的值和action,然后基于action的type决定如何处理state。
  注意:我们不会直接对state进行修改,而是重新创建一个对象,这样就可以使得我们能够获取历史数据。

Reducers的拆分

  当我们的功能越来越多时,如果我们只有一个Reducers,那么这个Reducers的职责会越来越大。这个时候我们就要考虑将这个Reducers进行拆分。
  参考Redux官方文档,假设我们现在的Reducers如下所示:

function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    default:
      return state
  }
}

function visibilityFilter(state = SHOW_ALL, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return action.filter
    default:
      return state
  }
}

function todoApp(state = {}, action) {
  return {
    visibilityFilter: visibilityFilter(state.visibilityFilter, action),
    todos: todos(state.todos, action)
  }
}

  如代码所示,todos和visibilityFilter是我们拆分出的两个Reducers,因为它们只是关注state上的部分数据,并不是全部的。所以我们通过todoApp只传递它们需要的数据,并在所有的Reducers执行完毕后使用最新数据更新state。当然了,Redux也提供为我们提供了combineReducers()来实现。
  通过combineReducers重新实现todoApp,如下所示:

import { combineReducers } from 'redux'

const todoApp = combineReducers({
  visibilityFilter,
  todos
})

export default todoApp

等价于

import { combineReducers } from 'redux'

const todoApp = combineReducers({
  visibilityFilter:visibilityFilter,
  todos:todos
})

export default todoApp

下面我们来看下combineReducers的关键源码,:

function combineReducers(reducers) {
  //1、首先获取Reducers的key
  //2、基于key,过滤出value为function的Reducers
  const reducerKeys = Object.keys(reducers)
  const finalReducers = {}
  for (let i = 0; i < reducerKeys.length; i++) {
    const key = reducerKeys[i]
    if (typeof reducers[key] === 'function') {
      finalReducers[key] = reducers[key]
    }
  }
  const finalReducerKeys = Object.keys(finalReducers)

  //在store.dispatch被执行时,combination方法会被执行。
  //1、初始化hasChanged为false
  //2、循环调用每个reducers,基于Reducers的key获取其关心的数据
  return function combination(state = {}, action) {
    let hasChanged = false
    const nextState = {}
    for (let i = 0; i < finalReducerKeys.length; i++) {
      const key = finalReducerKeys[i]
      const reducer = finalReducers[key]
      const previousStateForKey = state[key]
      const nextStateForKey = reducer(previousStateForKey, action)
      nextState[key] = nextStateForKey
      hasChanged = hasChanged || nextStateForKey !== previousStateForKey
    }
    return hasChanged ? nextState : state
  }
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值