React/redux,显示多个组件,共享相同的动作,但具有不同的状态

IT技术 reactjs redux
2021-05-23 04:52:19

假设我有一个可重复使用的容器。它是一个有多个页面的向导。

向导状态由 redux/actions 驱动。当一个动作被触发时,我使用一个减速器来更新我的状态。

如果我想复制多个向导并拥有自己的状态怎么办?

我认为必须有一种方法让某个动态减速器(可以创建/销毁)处理动作,然后让每个单独的向导从存储/状态的这些动态部分驱动。

这是推荐的吗?是否有图书馆可以让这更容易?

2个回答

只需将您的主状态划分为您需要的多个向导状态,并随每个操作发送一个向导 ID,以便您的减速器知道要处理哪个。

作为数组

{
  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;
  }
}

然后编写一个wizardsReducer了解如何减少向导列表的内容。

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

最后,用于combineReducers创建一个 root reducer,它将wizards属性的责任委托给 this 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
  };
}

OP 为此要求提供一个库,所以我只是把它扔在这里。

我创建了 infra 函数,它将拦截动作并添加meta-data到每个动作中。(以下FSA)您可以轻松地使用它来创建多个容器,而不会相互影响。

减速器动作拦截器