React router, how to restore state after browser back button? React router, how to restore state after browser back button? reactjs reactjs

React router, how to restore state after browser back button?


after a while I found a reasonable workaround:

  • in react, after every this.setState() I keep state synchronized with history using window.history.replaceState({ key: history.location.key, state: this.state})
  • when a "page" component is mounted or refreshed (willMount and willReceiveProps) I check for state in props.params.location.state: if there is one, I do restore it; if there is none I create a fresh new state.
  • when navigating on the same page, I do not use routes, I just use this.setState and window.history.pushState
  • when navigating outside of the page, I just use routes and avoid to pass anything in the state

This solution seems to work nicely, the only minor cons are:

  • state must be serializable
  • this.setState is a pitfall because it's asynchronous, you cannot use this.state after it, unless you do trickery.
  • initial empty state must be provided by a function to be used during the restore or init phase, it can't just stay in the constructor() of the Component
  • in Firefox, automatic scroll restoration after the back button works randomly, don't know why, but Chrome and Edge are ok.

Overall I have written a PageComponent that extends Component that does all the init/restoration work; it also overrides this.setState to make it syncs automatically with history and avoids the asynchronous annoyances.


Use getDerivedStateFromProps and check if there has been a change in value of props.location.key to restore states only when the user navigates with browser buttons.

 static getDerivedStateFromProps(props,states){         if ((typeof props.location !== 'undefined') &&             (typeof props.location.state !== 'undefined') &&              (states.location_key !== props.location.key)) {             let newState = props.location.state;             newState.location_key = props.location.key;             return newState;         }    }


You can also use the session storage instead of state. Just replace the useState() function and use the useSessionStorage().

For example:

const [myState, setMyState] = useSessionStorage("state_key", "initial_value")const handleSomeChangeOnState = (event: any) => {  setMyState("new_value")}