Итак, я работаю над большим приложением action/redux и очень доволен тем, насколько просто управлять состоянием в redux. Мы используем подход стиля "уток" к редукторам /action/action Creators, чтобы поддерживать отношения относительно домена. Кроме того, мы пытаемся сохранить состояние ui, связанное с доменом, и большинство редукторов имеют аналогичную структуру. Это выглядит примерно так:
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 внутри редуктора без необходимости добавлять в инструкции типа OPEN
и CLOSE
для ui в каждом редукторе. Может быть, я думаю о том, что это анти-шаблон в редуксе, но любопытно посмотреть, не сталкивался ли кто-нибудь с такой проблемой раньше?
UPDATE:
Мне нравится решение, перечисленное ниже, но как бы вы распространили редуктор на сортировку, содержащую в нем редуктор ui.
combineReducers({
home: {createUiReducer('home', initialState), ...home}
})
Таким образом, вы можете иметь вложенный домен на основе ui, не повторяя все действия. Не знаете, как вы это сделаете, потому что по существу вы будете динамически добавлять инструкции CASE.
Ну, вам нужно будет пропустить их с помощью префикса. Если вы, как и большинство разработчиков, ленивы, тогда создайте вспомогательную функцию, которая создаст вам редукторы;)
Как этот...
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"}
const OPEN = 'if-planning/home/OPEN';
Я думаю, что я не совсем понимаю, даже если бы у меня была вспомогательная функция, которая имела набор стандартных действий пользовательского интерфейса. Где бы я положил его в оригинальный редуктор?