Navigation dans React : pas seulement un clic sur un lien
\n\nAvez-vous déjà réfléchi à la façon de faire passer React Router à une autre page non pas par un clic de l'utilisateur, mais par une commande depuis le code ? Par exemple, après l'envoi réussi d'un formulaire, une authentification ou simplement après 5 secondes ? Si oui, vous êtes au bon endroit. La question "How can I programmatically navigate using React Router ?" est l'une des plus populaires sur Stack Overflow, et ce n'est pas pour rien. Cela semble simple, mais en réalité, de nombreux pièges se cachent, surtout en ce qui concerne les performances.
\n\nDans cet article, nous ne montrerons pas simplement comment utiliser useNavigate. Nous analyserons comment le faire correctement, rapidement et sans latence. Vous découvrirez quels modèles entraînent des fuites de mémoire et lesquels conduisent à une navigation fulgurante. C'est parti !
Classique : useNavigate — votre outil principal
\n\nDepuis React Router v6, useNavigate a remplacé le bon vieux useHistory. C'est un hook qui retourne la fonction navigate. Cela ressemble à ceci :
import { useNavigate } from 'react-router-dom';\n\nfunction LoginButton() {\n const navigate = useNavigate();\n\n const handleLogin = () => {\n // Logique d'authentification ici\n const user = { name: 'Иван' };\n // Après succès — redirection\n navigate('/dashboard', { replace: true });\n };\n\n return <button onClick={handleLogin}>Se connecter</button>;\n}\n\n\nNotez le paramètre { replace: true }. Il remplace l'entrée actuelle dans l'historique, plutôt que d'en ajouter une nouvelle. C'est crucial pour la connexion, afin que l'utilisateur ne puisse pas revenir en arrière vers la page de connexion.
Où peut-on naviguer ?
\n- \n
- Chemin absolu :
navigate('/about')\n - Chemin relatif :
navigate('../settings')\n - Retour/avance dans l'historique :
navigate(-1)ounavigate(2)\n
Niveau avancé : navigation en dehors des composants
\n\nEt si vous devez effectuer une redirection depuis une fonction ordinaire, en dehors d'un composant React ? Par exemple, depuis un action creator dans Redux ou depuis un intercepteur axios ? Le hook useNavigate ne fonctionnera pas ici — les hooks ne sont appelés qu'à l'intérieur des composants fonctionnels.
Solution : créer un composant wrapper personnalisé ou utiliser un objet routeur global. Dans React Router v6, il existe un composant spécial RouterProvider et createBrowserRouter, mais il existe aussi une méthode plus simple — sauvegarder une référence à navigate dans une variable.
// router.js\nimport { createBrowserRouter, RouterProvider } from 'react-router-dom';\n\nexport const router = createBrowserRouter([...]);\n\n// navigation.js — module séparé pour la navigation\nlet navigateFunction = null;\n\nexport const setNavigate = (navigate) => {\n navigateFunction = navigate;\n};\n\nexport const navigateTo = (path) => {\n if (navigateFunction) {\n navigateFunction(path);\n } else {\n console.warn('La navigation n'est pas encore prête');\n }\n};\n\n// App.js\nimport { useNavigate } from 'react-router-dom';\nimport { setNavigate } from './navigation';\nimport { useEffect } from 'react';\n\nfunction App() {\n const navigate = useNavigate();\n\n useEffect(() => {\n setNavigate(navigate);\n }, [navigate]);\n\n return /* votre code */;\n}\n\n\nMaintenant, depuis n'importe quelle fonction (que ce soit depuis setTimeout ou depuis fetch), vous pouvez appeler navigateTo('/home'). Pratique ? Oui. Sûr ? Seulement si vous n'oubliez pas de nettoyer la référence lors du démontage du composant.
Optimisation des performances : pourquoi votre application ralentit-elle ?
\n\nLa navigation programmatique n'est pas simplement un appel de fonction. C'est un déclencheur pour un re-rendu complet de la page. Et si vous le faites