也许我遗漏了一些非常明显的东西,但这让我今天被绊倒了。
假设我们有一个Redux存储,其结构如下:
const state = {
...
pages: {
...
accountPage: {
currentTab: 'dashboard',
fetching: false,
tableSettings: {
sortDir: 'asc',
sortField: 'name'
}
}
}
}所以很明显有一个主要的减速器...
export default combineReducers({
...
pages: pagesReducer
...
});然后页面的reducer就有了每个页面的reducer ...
export default combineReducers({
...
accountPage: accountPageReducer
...
});现在我们终于谈到了问题的核心,这个特殊状态的减速器。
export default handleActions({
[setCurrentTab]: (state, action) => { ... },
[setIsFetching]: (state, action) => { ... }
});这一切都很好,对吧?在tableSettings中,在一开始给出的状态中的关键字实际上应该由它自己的缩减程序来处理。此模式可能在状态中多次存在,因此它被抽象为一个reducer-creating函数:
const defaultState = {
sortDir: 'asc',
sortField: null
};
export const createTableSettingReducer (actions, extra ={}) => {
return handleActions({
[actions.changeSortDir]: (state, action) => ({ ...state, sortDir: action.payload }),
[actions.changeSortField]: (state, action) => ({ ...state, sortField: action.payload }),
...extra
}, defaultState)
}因此,在状态部分(accountPageReducer)的缩减程序之上,我们创建了缩减程序:
// pretend these actions were imported
const tableSettingsReducer = createTableSettingReducer({
changeSortDir: setSortDir,
changeSortField: setSortField
});所以问题是,我应该把tableSettingsReducer放在哪里?
当然,这不起作用:
export default handleActions({
[setCurrentTab]: (state, action) => { ... },
[setIsFetching]: (state, action) => { ... },
tableSettings: tableSettingsReducer
});它不起作用,因为handleActions希望使用动作常量作为键,而不是状态中的实际键。
也没有地方可以使用combineReducers,因为这个状态片只有一个嵌套的缩减程序。currentTab和fetching不需要自己的reducer,所以使用combineReducers是徒劳的。
我知道最近redux-actions开始支持嵌套的reducers...but,实际上没有任何文档可以确切地说明它是如何实现的,甚至没有描述实现它所需的参数。
我可以使用combineActions,并为嵌套reducer可以执行的每个操作组合handleActions中的所有操作。但这看起来并不是很clean...plus,如果嵌套的缩减程序有自己的嵌套缩减程序呢?这意味着每次这些reducers可以处理新的操作时,该操作都需要添加到其所有父级的combineActions中。不是最好的。
有什么想法?
发布于 2018-06-21 02:33:26
您所在州的每个键都有自己的缩减程序。有些reducers非常简单,有些是由其他reducers组成的。状态树的每个级别上的所有姐妹键都可以与combineReducers结合使用。
const initialCurrentTab = 'dashboard';
const currentTabReducer = handleActions({
[setCurrentTab]: (state, action) => {
return action.payload;
},
}, initialCurrentTab);
const defaultFetchingState = false;
const fetchingReducer = handleActions({
[setIsFetching]: (state, action) => {
return action.payload;
},
}, defaultFetchingState);
export default combineReducers({
currentTab: currentTabReducer,
fetching: fetchingReducer,
tableSettings: tableSettingsReducer,
});发布于 2020-02-05 05:52:34
let say you have the initialState = { data : []}
let assume that the upcoming action has payload of an array
export the reducer as the following :
return handleActions({
["Action Type 1" ]: (state, { payload }) => {
return { ...state, data: [...state.data, ...payload ]} ;
},
["Action Type 1" ]: (state, { payload }) => {
return { ...state, data: [...state.data, ...payload ]} ;
},
}, initialSate );
import this reducer in your combine reducer .https://stackoverflow.com/questions/46656475
复制相似问题