Создайте отдельные редукторы и объедините их:
function normalizeData(data, initialValue = [], idKey = 'id') {
return data.reduce(
(accumulator, currentValue) => ({
...accumulator,
[currentValue[idKey]]: currentValue,
}),
{},
);
}
function mapIds(data, initialValue = [], idKey = 'id') {
const ids = data.map(eachData => eachData[idKey]);
return [...initialValue, ids];
}
function posts(state = {}, action) {
switch (action.type) {
case types.FETCH_POSTS_SUCCESS:
return {
byId: normalizeData(action.payload.data, state.byId),
allIds: mapIds(action.payload.data, state.allIds),
};
default:
return state;
}
}
function users(state = {}, action) {
switch (action.type) {
case types.FETCH_USERS_SUCCESS:
return {
byId: normalizeData(action.payload.data, state.byId),
allIds: mapIds(action.payload.data, state.allIds),
};
default:
return state;
}
}
export default combineReducers({ posts, users });
Вы также можете создавать вспомогательные оболочки для них, которые можно использовать повторно для простого создания других редукторов сущностей:
const byIdReducerCreator = (actionType, idKey = 'id') => (state = {}, action) => {
switch (action.type) {
case types[actionType]:
return normalizeData(action.payload.data, state, idKey);
default:
return state;
}
};
const allIdReducerCreator = (actionType, idKey = 'id') => (state = [], action) => {
switch (action.type) {
case types[actionType]:
return mapIds(action.payload.data, state, idKey);
default:
return state;
}
};
const posts = combineReducers({
byId: byIdReducerCreator('FETCH_POSTS_SUCCESS'),
allIds: allIdReducerCreator('FETCH_POSTS_SUCCESS'),
});
const users = combineReducers({
byId: byIdReducerCreator('FETCH_USERS_SUCCESS', 'someOtherId'),
allIds: allIdReducerCreator('FETCH_USERS_SUCCESS', 'someOtherId'),
});
export default combineReducers({ posts, users });