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

后端 未结 2 2221
伪装坚强ぢ
伪装坚强ぢ 2021-02-20 06:16

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 upda

相关标签:
2条回答
  • 2021-02-20 06:38

    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
      };
    }
    
    0 讨论(0)
  • 2021-02-20 06:52

    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

    0 讨论(0)
提交回复
热议问题