Search code examples
reactjsreduxredux-framework

React-redux cross access state value


For last two weeks I have been working with redux and I'm facing an issue where I want to access/change a state value of another reducer. How can I achieve that?

For example: I have two components 'A-Component' and 'Message-component' which has 'A-actions', 'Message-actions' and 'A-reducer', 'Message-reducer' respectively

When an action of 'A-Component' is called it will call the corresponding reducer function where I need to update the Message-reducer state value which will display the message box

A-action


    export function add(data) {
      return {
        types: [types.ONADD, types.ONADDSUCCESS, types.ONADDFAIL],
        payload: {
          response: api.add(data).then(response => response),
          data
        }
      };
    }

A-reducer


    export default createReducer(initialState, {
      [types.ONADD](state) {
        return {
          ...state,
          message: 'Updating Records'
        };
      }
     });

The above mentioned message state value is message reducer's state value. I want to update the message state value from A-reducer which in turn updates the message component. Is this possible in redux?

I tried with various middleware but failed.

Thank in advance!


Solution

  • I think you're approaching this the wrong way. You should normalize your data as much as you can, and then maybe use the connect decorator to compose the state you need for your UI. For example, Messages could be nested under a "Friend"'s node, but it's better to have them in their own store, and then make a function that selects the messages from a friend based on a relationship. This gives you aggregations (You have 3 unread messages) for free. Take a look at reselect for a way to do this in a nice (and cached) way.

    Edit:

    You could write middleware which dispatches multiple actions:

    export default (store) => (next) => (action) => {
       if(!action.types){
         return next(action);
       }
    
       action.types.forEach(type => {
         next({
           type,
           payload: action.payload
         })
       });
    }
    

    Then call it from an Action Creator like so:

    export function addMessage(message){
      return {
        types: ['ADD_MESSAGE', 'UPDATE_USER'],
        payload: message
      }
    }