Search code examples
javascriptreactjsreduxredux-thunkredux-reducers

How to get a React Redux state value from the reducer?


In Redux, I currently have a state that looks something like the following.

{
  activeConversation: "Jim"
  conversations: (7) [{…}, {…}, {…}, {…}, {…}, {…}, {…}]
}

I'm also using socket.io to send messages to other users.

export const newMess = (body) => async (dispatch, getState) => {
  try {
    const {activeConversation} = getState();
    if (!body.conversationId) {
      dispatch(addConversation(body.recipientId, data.message));
    } else {
       dispatch(setNewMessage(data.message, activeConversation));
    }
    sendMessage(data, body, activeConversation);
  } catch (error) {
    console.error(error);
  }
};

From here, I then call my reducer function. The problem is with the variable activeConversation. Because I'm passing it through socket.io from thunk, it results in both users having the same activeConversation value which is not what I want (I want them to have different values). The problem is that I'm having trouble accessing the state. I got the state originally from thunk but that leads to the activeConversation from user 1 being passed to user 2 and I need to get the activeConversation value from each user. I'm wondering if it's possible to get the activeConversation state value from my reducer as opposed to thunk.


Solution

  • Your question is not very clear. However, if you want to get other state slices or the entire state in the reducer, you can use Sharing data between slice reducers.

    E.g.

    import { combineReducers, createStore } from 'redux';
    
    const SET_MESSAGE = 'SET_MESSAGE';
    export const setNewMessage = (message, sender) => {
      return {
        type: SET_MESSAGE,
        payload: { message, sender: sender || null },
      };
    };
    
    function activeConversationReducer(state = 'Jim', action) {
      return state;
    }
    function conversationsReducer(state = [1, 2, 3], action) {
      return state;
    }
    function userReducer(state = { id: 8, username: 'josh', email: '' }, action) {
      return state;
    }
    
    const combinedReducer = combineReducers({
      activeConversation: activeConversationReducer,
      conversations: conversationsReducer,
      user: userReducer,
    });
    
    function crossSliceReducer(state, action) {
      switch (action.type) {
        case SET_MESSAGE: {
          console.log('entire state:', state);
          // do something with state
          return state;
        }
        default:
          return state;
      }
    }
    
    function rootReducer(state, action) {
      const intermediateState = combinedReducer(state, action);
      const finalState = crossSliceReducer(intermediateState, action);
      return finalState;
    }
    
    const store = createStore(rootReducer);
    store.dispatch(setNewMessage('data', 'sender'));
    

    Execution result:

    entire state: {
      activeConversation: 'Jim',
      conversations: [ 1, 2, 3 ],
      user: { id: 8, username: 'josh', email: '' }
    }