Je souhaite que mon application ReactJS informe un utilisateur lorsqu'il quitte une page spécifique. Plus précisément, un message contextuel qui lui rappelle de faire une action:
"Les modifications sont enregistrées, mais pas encore publiées. Faites-le maintenant?"
Dois-je déclencher cela react-router
globalement, ou est-ce quelque chose qui peut être fait à partir de la page / composant de réaction?
Je n'ai rien trouvé sur ce dernier et je préfère éviter le premier. À moins que ce ne soit la norme, bien sûr, mais cela me fait me demander comment faire une telle chose sans avoir à ajouter du code à toutes les autres pages possibles auxquelles l'utilisateur peut accéder.
Toutes les informations sont les bienvenues, merci!
reactjs
react-router
Barry Staes
la source
la source
componentWillUnmount() { if (confirm('Changes are saved, but not published yet. Do that now?')) { // publish and go away from a specific page } else { // do nothing and go away from a specific page } }
pour que vous puissiez appeler votre fonction de publication avant de quitter la pageRéponses:
react-router
v4 introduit une nouvelle façon de bloquer la navigation à l'aide dePrompt
. Ajoutez simplement ceci au composant que vous souhaitez bloquer:Cela bloquera tout routage, mais pas l'actualisation ou la fermeture de la page. Pour bloquer cela, vous devrez ajouter ceci (mise à jour si nécessaire avec le cycle de vie React approprié):
onbeforeunload a divers supports par les navigateurs.
la source
onberforeunload
alerte.react-router
ne prend pas en charge cela par défaut (en supposant que le bouton d'annulation ne déclenche aucun changement d'itinéraire). Vous pouvez cependant créer votre propre modal pour imiter le comportement.onbeforeunload
finissez par utiliser , vous voudrez le nettoyer lorsque votre composant se démonte.componentWillUnmount() { window.onbeforeunload = null; }
Dans react-router
v2.4.0
ou au-dessus et avantv4
il y a plusieurs optionsonLeave
pourRoute
setRouteLeaveHook
pourcomponentDidMount
Vous pouvez empêcher une transition de se produire ou demander à l'utilisateur de quitter une route avec un crochet de sortie.
Notez que cet exemple utilise le
withRouter
composant d'ordre supérieur introduit dansv2.4.0.
Cependant, cette solution ne fonctionne pas parfaitement lors du changement manuel de l'itinéraire dans l'URL
Dans le sens où
Pour
react-router v4
utiliser l'invite ou l'historique personnalisé:Cependant
react-router v4
, c'est plutôt plus facile à implémenter avec l'aide dePrompt
from'react-routerSelon la documentation
Dans votre méthode de rendu, vous devez simplement l'ajouter comme indiqué dans la documentation en fonction de vos besoins.
METTRE À JOUR:
Au cas où vous souhaiteriez avoir une action personnalisée à entreprendre lorsque l'utilisation quitte la page, vous pouvez utiliser l'historique personnalisé et configurer votre routeur comme
history.js
puis dans votre composant, vous pouvez utiliser
history.block
commela source
<Prompt>
l'URL est modifiée lorsque vous appuyez sur Annuler à l'invite. ProblèmePour
react-router
2.4.0+REMARQUE : il est conseillé de migrer tout votre code vers le dernier
react-router
pour obtenir tous les nouveaux goodies.Comme recommandé dans la documentation de react-router :
Il faut utiliser le
withRouter
composant d'ordre supérieur:Comme exemple ES6 de la documentation:
la source
Pour
react-router
v3.xJ'ai eu le même problème où j'avais besoin d'un message de confirmation pour toute modification non enregistrée sur la page. Dans mon cas, j'utilisais React Router v3 , donc je ne pouvais pas utiliser
<Prompt />
, qui a été introduit à partir de React Router v4 .J'ai géré le «clic sur le bouton retour» et le «clic sur un lien accidentel» avec la combinaison de
setRouteLeaveHook
ethistory.pushState()
, et j'ai géré le «bouton de rechargement» avec leonbeforeunload
gestionnaire d'événements.setRouteLeaveHook ( doc ) et history.pushState ( doc )
Utiliser uniquement setRouteLeaveHook ne suffisait pas. Pour une raison quelconque, l'URL a été modifiée bien que la page soit restée la même lorsque l'utilisateur a cliqué sur le bouton de retour.
onbeforeunload ( doc )
Il est utilisé pour gérer le bouton de `` rechargement accidentel ''
Voici le composant complet que j'ai écrit
this.props.router
.this.props.route
est transmis par le composant appelantnotez qu'il
currentState
est passé comme accessoire pour avoir l'état initial et pour vérifier tout changementS'il vous plaît laissez-moi savoir s'il y a des questions :)
la source
Pour
react-router
v0.13.x avecreact
v0.13.x:cela est possible avec les méthodes
willTransitionTo()
etwillTransitionFrom()
static. Pour les versions plus récentes, voir mon autre réponse ci-dessous.À partir de la documentation de react-router :
Pour
react-router
1.0.0-rc1 avecreact
v0.14.x ou version ultérieure:cela devrait être possible avec le
routerWillLeave
hook de cycle de vie. Pour les anciennes versions, voir ma réponse ci-dessus.À partir de la documentation de react-router :
Des choses. peut changer avant la version finale.
la source
Vous pouvez utiliser cette invite.
la source
Utilisation de history.listen
Par exemple comme ci-dessous:
Dans votre composant,
la source