2

I have two reducers combined using combineReducers()

  1. UI Reducer has a 'isLoginOpen' key (true/false) - When true a login modal appears.
  2. Auth Reducer has 'isAuthenticated' key - (true/false) Which states if the user is logged in

I also have an action creator called OpenLoginModal() which causes the UI reducer to make 'isLoginOpen' to become true.

I only want to allow this behavior when 'isAuthenticated' is false. I.E, I only allow to show the login modal when the user isn't logged in.

The problem is: 'isAuthenticated' is in a different reducer, and I don't want to duplicate it to UI reducer.

How should I resolve this issue?

Poogy
  • 2,597
  • 7
  • 20
  • 35
  • You could have your action take in the `isAuth` state, and then use it within the reducer. You could also just have a local `isAuth` in the UI reducer which is triggered when the real `isAuth` has a value. – Colin Ricardo Apr 26 '18 at 13:24
  • If you don't mind re-coding your reducers a bit you can try [redux-named-reducers](https://www.npmjs.com/package/redux-named-reducers) which allows you access other reducer's state while still using combineReducers. – miles_christian Apr 26 '18 at 22:39
  • 1
    Possible duplicate of [Accessing a part of reducer state from one reducer within another reducer](https://stackoverflow.com/questions/42239302/accessing-a-part-of-reducer-state-from-one-reducer-within-another-reducer) – Greg K Aug 29 '18 at 10:08

2 Answers2

2

Reducers should be concerned about updating the state.

You should use selectors to calculate the state of the application including which actions are allowed.

In your case the code calling the action creator (or the action creator itself if using thunk) can select both values from the store and decide what to do.

thedude
  • 9,388
  • 1
  • 29
  • 30
  • Thanks for the quick answer. My action creator is a simple function which returns an action object (type, payload). So, I don't want it to dispatch anything if user is authenticated. What should it return? null? – Poogy Apr 26 '18 at 13:27
2

Per the Redux FAQ entry on sharing state between reducers:

Many users later want to try to share data between two reducers, but find that combineReducers does not allow them to do so. There are several approaches that can be used:

  • If a reducer needs to know data from another slice of state, the state tree shape may need to be reorganized so that a single reducer is handling more of the data.

  • You may need to write some custom functions for handling some of these actions. This may require replacing combineReducers with your own top-level reducer function. You can also use a utility such as reduce-reducers to run combineReducers to handle most actions, but also run a more specialized reducer for specific actions that cross state slices.

  • Async action creators such as redux-thunk have access to the entire state through getState(). An action creator can retrieve additional data from the state and put it in an action, so that each reducer has enough information to update its own state slice.

Given your use case, I'd suggest writing a thunk action creator that checks state.auth.isAuthenticated, and only dispatches the action if that's false.

markerikson
  • 63,178
  • 10
  • 141
  • 157