after a while I found a reasonable workaround:
- in react, after every
this.setState()I keep state synchronized with history usingwindow.history.replaceState({ key: history.location.key, state: this.state}) - when a “page” component is mounted or refreshed (
willMountandwillReceiveProps) I check for state inprops.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.setStateandwindow.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.setStateis a pitfall because it’s asynchronous, you cannot usethis.stateafter 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 theComponent - 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.