web-dev-qa-db-fra.com

React router, comment restaurer l'état après le bouton de retour du navigateur?

J'essaie de comprendre comment faire pour que mon React application SPA maintienne l'état lorsque l'utilisateur navigue avec les boutons du navigateur arrière/avant. Par exemple, l'utilisateur remplit un formulaire, puis il recule et vers l'avant et le formulaire est automatiquement restauré.

J'ai passé en revue de nombreux routeurs JavaScript, mais aucun ne semble résoudre ce problème correctement ... (ou même pas du tout).

Actuellement, j'utilise React Router 4 et c'est le modèle que j'adopte:

  1. lorsque je quitte la page par programme, j'enregistre d'abord l'état de la page actuelle avec history.replace(this.state); puis je quitte la page avec history.Push(newLocation)
  2. lorsqu'un composant de page est créé (componentWillMount) je vérifie this.props.location.state !== undefined et si c'est le cas, je le restaure avec this.setState(this.props.location.state)

Ma question est: le modèle ci-dessus est-il correct? suggéré? Existe-t-il un moyen meilleur et largement adopté?

13
nino.porcino

après un certain temps, j'ai trouvé une solution de contournement raisonnable:

  • en réaction, après chaque this.setState() je garde l'état synchronisé avec l'historique en utilisant window.history.replaceState({ key: history.location.key, state: this.state})
  • lorsqu'un composant "page" est monté ou actualisé (willMount et willReceiveProps) je vérifie l'état dans props.params.location.state: s'il y en a un, je le restaure; s'il n'y en a pas, je crée un nouvel état.
  • lorsque je navigue sur la même page, je n'utilise pas de routes, j'utilise simplement this.setState et window.history.pushState
  • lorsque je navigue en dehors de la page, j'utilise simplement des itinéraires et évite de passer quoi que ce soit dans l'état

Cette solution semble bien fonctionner, les seuls inconvénients mineurs sont:

  • l'état doit être sérialisable
  • this.setState Est un piège car il est asynchrone, vous ne pouvez pas utiliser this.state Après, sauf si vous faites de la supercherie.
  • l'état vide initial doit être fourni par une fonction à utiliser pendant la phase de restauration ou d'initialisation, il ne peut pas simplement rester dans la constructor() de la Component
  • dans Firefox, la restauration automatique du défilement après le bouton retour fonctionne de manière aléatoire, je ne sais pas pourquoi, mais Chrome et Edge sont ok.

Dans l'ensemble, j'ai écrit un PageComponent qui étend Component qui fait tout le travail d'initialisation/restauration; il remplace également this.setState pour le synchroniser automatiquement avec l'historique et évite les désagréments asynchrones.

10
nino.porcino