Search code examples
reduxreact-reduxreact-router-redux

How to add properties to react-router-redux LOCATION_CHANGE?


I am writing an application using react-router-redux. When the LOCATION_CHANGE action is dispatched, I want to update the UI to show progress based on how far in a survey the user is. My state has this structure:

ui: {
  progress: 0
},
survey: {
  question1: true,
  question2: null
}

I have a function that loops through the questions in the survey property and can determine the progress based on the first instance of a question being null. In the above example, the progress will be 1 as question2 is null (yet to be answered).

To update the UI, I have a UI reducer subscribed to the @@router/LOCATION_CHANGE action, in which I can run the function to determine progress.

The problem I am facing is that in the UI reducer, I only have access to the UI state and the payload from LOCATION_CHANGE, not the survey.

Is it possible to modify LOCATION_CHANGE to include additional properties in its payload?


Solution

  • The best way to solve your problem in my opinion is to use a middleware to intercept all @@router/LOCATION_CHANGE actions and execute your logic before it reaches the reducer. You have the getState function available in middleware so you can read both ui and survery states.

    Middleware

    export default ({ dispatch, getState }) => (next) => (action) => {
      if (action.type === '@@router/LOCATION_CHANGE') {
        const state = getState(); // this is the whole redux state
        const progress = getNewProgressValue(state);
        dispatch(updateProgress(progress)); // updateProgress is the action creator to update progress value
      }
      next(action);
    }
    

    You also need to modify your reducer to update progress based on action dispatched by updateProgress action creator.

    NOTE: I'm assuming you're not using redux-saga. If you are, you can still get the idea from this method.