Reducer返回reducer结果的集合

时间:2017-06-22 20:57:53

标签: reactjs redux

我有一个看起来像这样的减速器:

const chart = combineReducers({
    data,   
    fetchProgress,
    fetchError,
    updateProgress,
    updateError,
});

我现在不仅想要一张图表,还想要多张图表。

const charts = (state = {}, action = {}) => {
    if (action.type == FETCH_CHART || action.type == ...) { 
        let newChart = chart(state[action.id], action);
        return Object.assign({}, state, {[action.id]: newChart});
    }
    return state;
}

这样做有什么概念上的错误吗?

如果不是,是否有更好的方法可以达到相同的效果?

2 个答案:

答案 0 :(得分:1)

这个概念没有错。事实上,当我需要在redux商店中存储类似的数据时,我说这是我的首选方法

要改进它,您可以将其包装在更高阶的缩减器中以处理它的id部分。类似的东西:

const handleIds = (reducer) => (state = {}, action) => {
    if (action.id) {
        let idState = state[action.id]
        let newState = reducer(idState, action)

        if (newState !== idState) {
            return  { ...state, [action.id]: newState }
        }
    }

    return state
}

这将传递id的所有操作,并将生成的statestate id合并为state ,如果const singleChart = (state = {}, action = {}) => { if (action.type == FETCH_CHART || action.type == ...) { let newChart = chart(state, action); return newChart; } return state; } const charts = handleIds(singleChart) 已更改。

然后你的减速器变成:

const chart = combineReducers({
    data,   
    fetchProgress,
    fetchError,
    updateProgress,
    updateError,
    charts
});

然后将它组合到您的商店中:

git pull origin master --allow-unrelated-histories

答案 1 :(得分:1)

就我个人而言,我会将逻辑分解为进一步减少子,以便更好地分离关注点。如果您要添加多个图表,并且您需要在操作中添加更多逻辑/设置/数据,最终您将修改过多的单个减速器。

我按照一个小例子,你可以有3个图表。

// bubbleChartReducer.js
export function bubble (state = {}, action) {
  switch (action.type) {
    case 'FETCH_BUBBLE_CHART': 
      return {
        [action.id]: new chart(action.id, action)
      }
    default:
      return state
  }
}

// pieChartReducer.js
export function pie (state = {}, action) {
  switch (action.type) {
    case 'FETCH_PIE_CHART': 
      return {
        [action.id]: new chart(action.id, action)
      }
    default:
      return state
  }
}

// linearChartReducer.js
export function pie (state = {}, action) {
  switch (action.type) {
    case 'FETCH_LINEAR_CHART': 
      return {
        [action.id]: new chart(action.id, action)
      }
    default:
      return state
  }
}



// chartsReducer.js
import { bubble } from 'bubbleChartReducer'
import { pie } from 'pieChartReducer'
import { linear } from 'linearChartReducer'
import { combineReducers } from 'redux'

export combineReducers({
  bubble,
  pie,
  linear
})