Reactjs 返回一组Reducer结果的Reducer

Reactjs 返回一组Reducer结果的Reducer,reactjs,redux,Reactjs,Redux,我有一个减速器,看起来像这样: const chart = combineReducers({ data, fetchProgress, fetchError, updateProgress, updateError, }); 我现在不仅想要一张图表,还要多张图表 const charts = (state = {}, action = {}) => { if (action.type == FETCH_CHART || action

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

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;
}
这样做在概念上有什么错误吗


如果没有,有没有更好的方法达到同样的效果?

这个概念没有错。事实上,当需要在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的操作,并将生成的
状态
合并到其
状态
,并将该
id
作为键

然后你的减速器变成:

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
});

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

下面我举一个小例子,其中可以有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
})