在 redux 中跨多个 reducer 重用操作
Reusing actions across multiple reducers in redux
所以我正在开发一个大型 react/redux 应用程序,并且对它在 redux 中管理状态的简单性感到非常满意。我们正在对 reducers/action/action Creators 使用 "ducks" 风格的方法来保持相对基于域的事物。此外,我们尝试保持 ui 状态与域关联,并且大多数 reducer 具有相似的结构。它看起来像这样:
export default function home(state = initialState, action = {}) {
switch (action.type) {
case OPEN:
return {
...state,
ui: {
...state.ui,
[action.key]: true
}
};
case CLOSE:
return {
...state,
ui: {
...state.ui,
[action.key]: false
}
};
case SELECT_TAB:
return {
...state,
ui: {
selectedTab: action.selected
}
};
default:
return state;
}
}
我们最终对 ui 重复了相同的操作,主要是切换和设置显示的内容。有没有一种方法可以将基于域的 ui 保留在 reducer 中,而不必在每个 reducer 中为 ui 添加 OPEN
和 CLOSE
类型语句。也许我在想的是 redux 中的反模式,但很想知道以前是否有人 运行 遇到过此类问题?
更新:
我喜欢下面列出的解决方案,但您将如何扩展减速器以在其中包含一个 ui 减速器。
combineReducers({
home: {createUiReducer('home', initialState), ...home}
})
这样您就可以拥有基于嵌套域的 ui 而无需重复所有操作。不确定你会怎么做,因为你实际上是在动态添加 CASE 语句。
好吧,您需要使用前缀为它们命名空间。如果你像大多数开发人员一样懒惰,那么创建一个辅助函数来为你生成 reducer ;)
喜欢这个..
const createOpenCloseReducer = (prefix, initialState) => {
const = ui = prefix + "_UI";
return (state = initialState, action) => {
switch(action.type) {
case (prefix + "_CLOSE"):
return { ...state, [ui]: "CLOSED" }
case (prefix + "_OPEN"):
return { ...state, [ui]: "OPENED" }
default:
return state
}
}
}
import { combineReducers, createStore } from 'redux';
const rootReducer = combineReducers({
home: combineReducers({
ui: createOpenCloseReducer("HOME", { "HOME_UI": "CLOSED" }),
data: someOtherHomeDataReducer
}),
someOther: createOpenCloseReducer("OTHER", { "OTHER_UI": "CLOSED" })
})
store = createStore(rootReducer)
// use it..
store.dispatch({type: "HOME_CLOSE"})
store.dispatch({type: "OTHER_OPEN"})
// your state..
store.getState().home.ui // {HOME_UI: "CLOSED"}
store.getState().someOther // {OTHER_UI: "OPENED"}
所以我正在开发一个大型 react/redux 应用程序,并且对它在 redux 中管理状态的简单性感到非常满意。我们正在对 reducers/action/action Creators 使用 "ducks" 风格的方法来保持相对基于域的事物。此外,我们尝试保持 ui 状态与域关联,并且大多数 reducer 具有相似的结构。它看起来像这样:
export default function home(state = initialState, action = {}) {
switch (action.type) {
case OPEN:
return {
...state,
ui: {
...state.ui,
[action.key]: true
}
};
case CLOSE:
return {
...state,
ui: {
...state.ui,
[action.key]: false
}
};
case SELECT_TAB:
return {
...state,
ui: {
selectedTab: action.selected
}
};
default:
return state;
}
}
我们最终对 ui 重复了相同的操作,主要是切换和设置显示的内容。有没有一种方法可以将基于域的 ui 保留在 reducer 中,而不必在每个 reducer 中为 ui 添加 OPEN
和 CLOSE
类型语句。也许我在想的是 redux 中的反模式,但很想知道以前是否有人 运行 遇到过此类问题?
更新:
我喜欢下面列出的解决方案,但您将如何扩展减速器以在其中包含一个 ui 减速器。
combineReducers({
home: {createUiReducer('home', initialState), ...home}
})
这样您就可以拥有基于嵌套域的 ui 而无需重复所有操作。不确定你会怎么做,因为你实际上是在动态添加 CASE 语句。
好吧,您需要使用前缀为它们命名空间。如果你像大多数开发人员一样懒惰,那么创建一个辅助函数来为你生成 reducer ;)
喜欢这个..
const createOpenCloseReducer = (prefix, initialState) => {
const = ui = prefix + "_UI";
return (state = initialState, action) => {
switch(action.type) {
case (prefix + "_CLOSE"):
return { ...state, [ui]: "CLOSED" }
case (prefix + "_OPEN"):
return { ...state, [ui]: "OPENED" }
default:
return state
}
}
}
import { combineReducers, createStore } from 'redux';
const rootReducer = combineReducers({
home: combineReducers({
ui: createOpenCloseReducer("HOME", { "HOME_UI": "CLOSED" }),
data: someOtherHomeDataReducer
}),
someOther: createOpenCloseReducer("OTHER", { "OTHER_UI": "CLOSED" })
})
store = createStore(rootReducer)
// use it..
store.dispatch({type: "HOME_CLOSE"})
store.dispatch({type: "OTHER_OPEN"})
// your state..
store.getState().home.ui // {HOME_UI: "CLOSED"}
store.getState().someOther // {OTHER_UI: "OPENED"}