React/redux, отображение нескольких компонентов, совместное использование одних и тех же действий, но с разным состоянием

Скажем, у меня есть многоразовый контейнер. Это мастер с несколькими страницами.

Состояние мастера управляется сокращением/действием. Когда действие запускается, я использую редуктор для обновления состояния.

Что делать, если я хочу дублировать несколько мастеров с собственным состоянием?

Я думаю, что должен быть способ иметь действия, которые обрабатываются определенным динамическим редуктором (который может быть создан/уничтожен), а затем каждый индивидуальный мастер управляется из этих динамических частей хранилища/состояния.

Это рекомендуется? Являются ли библиотеки там, которые облегчают это?

Ответ 1

Просто разделяйте основное состояние на столько состояний мастера, сколько вам нужно, и отправляйте идентификатор мастера вместе с каждым действием, чтобы ваш редуктор знал, какой из них нужно решать.

Как массив

{
  wizards: [
    { id: 'A', state: true },
    { id: 'B', state: false },
    { id: 'C', state: true }
  ]
}

Вы можете написать мастер-редуктор, который понимает, как уменьшить одно состояние мастера.

function wizardReducer(wizard, action) {
  switch(action) {
    case 'TOGGLE':
      return {
        id: wizard.id,
        state: !wizard.state
      };
    default:
      return wizard;
  }
}

Затем напишите a wizardsReducer, который понимает, как уменьшить список мастеров.

function wizardsReducer(wizards, action) {
  return wizards.map(function(wizard) {
    if(action.id == wizard.id) {
      return wizardReducer(wizard, action);
    } else {
      return wizard;
    }
  });
}

Наконец, используйте combineReducers для создания корневого редуктора, который делегирует ответственность за свойство wizards для этого wizardsReducer.

combineReducers({
  wizards: wizardsReducer
});

Как объект

Если вместо этого вы сохраняете своих мастеров в объекте, вам придется немного по-своему построить wizardsReducer.

{
  wizards: {
    A: { id: 'A', state: true },
    B: { id: 'B', state: false },
    C: { id: 'C', state: true }
  }
}

Не было бы смысла отображать состояния, когда мы можем просто выбрать нужное нам состояние.

function wizardsReducer(wizards, action) {
  if(!(action.id in wizards)) return wizards;

  const wizard = wizards[action.id];
  const updatedWizard = wizardReducer(wizard, action);

  return {
    ...wizards,
    [action.id]: updatedWizard
  };
}

Ответ 2

OP попросил lib для этого, поэтому я просто бросаю его сюда.

Я создал функции infra, которые будут перехватывать действия и добавлять meta-data к каждому действию. (после FSA) Вы можете легко использовать это для создания нескольких контейнеров без их влияния друг на друга.

reducer-action-interceptor