React/redux, displaying multiple components, sharing same actions, but with different state

匿名 (未验证) 提交于 2019-12-03 02:56:01

问题:

Let's say I have a reusable container. It is a wizard with multiple pages.

The wizard state is driven by redux/actions. When an action is fired, I use a reducer to update my state.

What if I want to have multiple wizards duplicated, with it's own state?

I am thinking there must be a way to have actions handled by a certain dynamic reducer (that can be created/destroyed), and then have each individual wizard driven from these dynamic pieces of the store/state.

Is this recommended? Are the libraries out there that make this easier?

回答1:

Just partition your main state into as many wizard states as you need and send a wizard id along with each action so that your reducer knows which one to tackle.

As Array

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

You can write a wizard reducer which understands how to reduce a single wizard state.

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

Then write a wizardsReducer which understands how to reduce a list of wizards.

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

Finally, use combineReducers to create a root reducer which delegates responsibility for the wizards property to this wizardsReducer.

combineReducers({   wizards: wizardsReducer });

As Object

If you're storing your wizards in an object instead, you'll have to construct your wizardsReducer slightly differently.

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

It wouldn't make much sense to map over the states, when we can just select the state we need straight away.

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:

The OP asked for a lib for this, so I am just throwing it here.

I created infra functions which will intercept the actions and add meta-data to each action. (following FSA) You can use this easily to create multiple containers without them affecting each other.

reducer-action-interceptor



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!