Повторное использование действий через несколько редукторов в Redux

7

Итак, я работаю над большим приложением 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.

Теги:
react-redux
redux

1 ответ

6
Лучший ответ

Ну, вам нужно будет пропустить их с помощью префикса. Если вы, как и большинство разработчиков, ленивы, тогда создайте вспомогательную функцию, которая создаст вам редукторы;)

Как этот...

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"}
  • 0
    Спасибо за ответ, однако у меня уже есть каждое пространство имен, похожее на const OPEN = 'if-planning/home/OPEN'; Я думаю, что я не совсем понимаю, даже если бы у меня была вспомогательная функция, которая имела набор стандартных действий пользовательского интерфейса. Где бы я положил его в оригинальный редуктор?
  • 0
    @PhilipChmalts проверить правки .. вот как я бы это использовал ..
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню