useRouter
Si vous souhaitez accéder à l'objet router
dans n'importe quel composant fonction de votre application, vous pouvez utiliser le hook useRouter
. Voici un exemple :
useRouter
est un Hook React, ce qui signifie qu'il ne peut pas être utilisé avec des classes. Vous pouvez soit utiliser withRouter, soit encapsuler votre classe dans un composant fonction.
Objet router
Voici la définition de l'objet router
retourné par useRouter
et withRouter
:
pathname
:String
- Le chemin du fichier de route actuel qui vient après/pages
. Par conséquent,basePath
,locale
et la barre oblique finale (trailingSlash: true
) ne sont pas inclus.query
:Object
- La chaîne de requête analysée sous forme d'objet, incluant les paramètres des routes dynamiques. Ce sera un objet vide pendant le pré-rendu si la page n'utilise pas le rendu côté serveur (SSR). Par défaut :{}
asPath
:String
- Le chemin tel qu'affiché dans le navigateur, incluant les paramètres de recherche et respectant la configurationtrailingSlash
.basePath
etlocale
ne sont pas inclus.isFallback
:boolean
- Indique si la page actuelle est en mode de repli (fallback).basePath
:String
- Le basePath actif (si activé).locale
:String
- La locale active (si activée).locales
:String[]
- Toutes les locales supportées (si activées).defaultLocale
:String
- La locale par défaut actuelle (si activée).domainLocales
:Array<{domain, defaultLocale, locales}>
- Les locales configurées par domaine.isReady
:boolean
- Indique si les champs du routeur sont mis à jour côté client et prêts à l'emploi. Ne doit être utilisé qu'à l'intérieur de méthodesuseEffect
et non pour un rendu conditionnel côté serveur. Voir la documentation associée pour les cas d'utilisation avec les pages automatiquement optimisées statiquementisPreview
:boolean
- Indique si l'application est actuellement en mode de prévisualisation.
L'utilisation du champ
asPath
peut entraîner une incohérence entre le client et le serveur si la page est rendue côté serveur ou avec une optimisation statique automatique. Évitez d'utiliserasPath
tant que le champisReady
n'est pastrue
.
Les méthodes suivantes sont incluses dans router
:
router.push
Gère les transitions côté client. Cette méthode est utile lorsque next/link
ne suffit pas.
url
:UrlObject | String
- L'URL vers laquelle naviguer (voir la documentation du module URL de Node.JS pour les propriétés deUrlObject
).as
:UrlObject | String
- Décorateur optionnel pour le chemin qui sera affiché dans la barre d'URL du navigateur. Avant Next.js 9.5.3, cela était utilisé pour les routes dynamiques.options
- Objet optionnel avec les options de configuration suivantes :scroll
- Booléen optionnel, contrôle le défilement vers le haut de la page après la navigation. Par défaut :true
shallow
: Met à jour le chemin de la page actuelle sans réexécutergetStaticProps
,getServerSideProps
ougetInitialProps
. Par défaut :false
locale
- Chaîne optionnelle, indique la locale de la nouvelle page
Vous n'avez pas besoin d'utiliser
router.push
pour les URL externes. window.location est plus adapté pour ces cas.
Navigation vers pages/about.js
, qui est une route prédéfinie :
Navigation vers pages/post/[pid].js
, qui est une route dynamique :
Redirection de l'utilisateur vers pages/login.js
, utile pour les pages protégées par une authentification :
Réinitialisation de l'état après navigation
Lors de la navigation vers la même page dans Next.js, l'état de la page ne sera pas réinitialisé par défaut, car React ne démonte pas le composant sauf si le composant parent a changé.
Dans l'exemple ci-dessus, naviguer entre /one
et /two
ne réinitialisera pas le compteur. Le useState
est maintenu entre les rendus car le composant React de haut niveau, Page
, est le même.
Si vous ne voulez pas ce comportement, vous avez plusieurs options :
-
Mettre à jour manuellement chaque état avec
useEffect
. Dans l'exemple ci-dessus, cela pourrait ressembler à : -
Utiliser une
key
React pour indiquer à React de remonter le composant. Pour le faire sur toutes les pages, vous pouvez utiliser une application personnalisée :pages/_app.js
Avec un objet URL
Vous pouvez utiliser un objet URL de la même manière que pour next/link
. Fonctionne pour les paramètres url
et as
:
router.replace
Similaire à la prop replace
de next/link
, router.replace
empêche l'ajout d'une nouvelle entrée d'URL dans la pile history
.
- L'API de
router.replace
est exactement la même que celle derouter.push
.
Voici un exemple :
router.prefetch
Précharge les pages pour des transitions côté client plus rapides. Cette méthode n'est utile que pour les navigations sans next/link
, car next/link
s'occupe de précharger les pages automatiquement.
Cette fonctionnalité est uniquement disponible en production. Next.js ne précharge pas les pages en développement.
url
- L'URL à précharger, incluant les routes explicites (par ex./dashboard
) et dynamiques (par ex./product/[id]
)as
- Décorateur optionnel poururl
. Avant Next.js 9.5.3, cela était utilisé pour précharger les routes dynamiques.options
- Objet optionnel avec les champs autorisés suivants :locale
- permet de fournir une locale différente de celle active. Sifalse
,url
doit inclure la locale car la locale active ne sera pas utilisée.
Imaginons que vous ayez une page de connexion, et qu'après la connexion, vous redirigez l'utilisateur vers le tableau de bord. Pour ce cas, nous pouvons précharger le tableau de bord pour une transition plus rapide, comme dans l'exemple suivant :
router.beforePopState
Dans certains cas (par exemple, si vous utilisez un serveur personnalisé), vous pouvez souhaiter écouter les événements popstate et effectuer une action avant que le routeur n'agisse.
cb
- La fonction à exécuter lors des événementspopstate
entrants. La fonction reçoit l'état de l'événement sous forme d'objet avec les props suivantes :url
:String
- la route pour le nouvel état. Il s'agit généralement du nom d'unepage
as
:String
- l'URL qui sera affichée dans le navigateuroptions
:Object
- Options supplémentaires envoyées par router.push
Si cb
retourne false
, le routeur Next.js ne gérera pas popstate
, et vous serez responsable de le gérer dans ce cas. Voir Désactivation du routage par système de fichiers.
Vous pouvez utiliser beforePopState
pour manipuler la requête ou forcer un rafraîchissement SSR, comme dans l'exemple suivant :
router.back
Navigue en arrière dans l'historique. Équivalent à cliquer sur le bouton retour du navigateur. Exécute window.history.back()
.
router.reload
Recharge l'URL actuelle. Équivalent à cliquer sur le bouton rafraîchir du navigateur. Exécute window.location.reload()
.
router.events
Vous pouvez écouter différents événements se produisant dans le routeur Next.js. Voici une liste des événements supportés :
routeChangeStart(url, { shallow })
- Se déclenche lorsqu'une route commence à changerrouteChangeComplete(url, { shallow })
- Se déclenche lorsqu'une route a complètement changérouteChangeError(err, url, { shallow })
- Se déclenche lorsqu'il y a une erreur lors du changement de route, ou qu'un chargement de route est annuléerr.cancelled
- Indique si la navigation a été annulée
beforeHistoryChange(url, { shallow })
- Se déclenche avant de changer l'historique du navigateurhashChangeStart(url, { shallow })
- Se déclenche lorsque le hash va changer mais pas la pagehashChangeComplete(url, { shallow })
- Se déclenche lorsque le hash a changé mais pas la page
Bon à savoir : Ici,
url
est l'URL affichée dans le navigateur, incluant lebasePath
.
Par exemple, pour écouter l'événement routeChangeStart
du routeur, ouvrez ou créez pages/_app.js
et abonnez-vous à l'événement, comme ceci :
Nous utilisons une application personnalisée (Custom App) (
pages/_app.js
) pour cet exemple afin de nous abonner à l'événement car elle n'est pas démontée lors des navigations de page, mais vous pouvez vous abonner aux événements du routeur dans n'importe quel composant de votre application.
Les événements du routeur doivent être enregistrés lorsqu'un composant est monté (useEffect ou componentDidMount / componentWillUnmount) ou impérativement lorsqu'un événement se produit.
Si un chargement de route est annulé (par exemple, en cliquant rapidement sur deux liens à la suite), routeChangeError
se déclenchera. Et l'err
passé contiendra une propriété cancelled
définie à true
, comme dans l'exemple suivant :
L'export next/compat/router
Il s'agit du même hook useRouter
, mais qui peut être utilisé à la fois dans les répertoires app
et pages
.
Il diffère de next/router
en ce qu'il ne génère pas d'erreur lorsque le routeur de pages n'est pas monté, et a plutôt un type de retour NextRouter | null
.
Cela permet aux développeurs de convertir des composants pour qu'ils fonctionnent à la fois dans app
et pages
lors de la transition vers le routeur app
.
Un composant qui ressemblait précédemment à ceci :
Générera une erreur lors de la conversion vers next/compat/router
, car null
ne peut pas être déstructuré. À la place, les développeurs pourront utiliser de nouveaux hooks :
Ce composant fonctionnera maintenant dans les répertoires pages
et app
. Lorsque le composant n'est plus utilisé dans pages
, vous pouvez supprimer les références au routeur de compatibilité :
Utilisation de useRouter
en dehors du contexte Next.js dans les pages
Un autre cas d'usage spécifique est le rendu de composants en dehors du contexte d'une application Next.js, comme dans getServerSideProps
du répertoire pages
. Dans ce cas, le routeur de compatibilité peut être utilisé pour éviter les erreurs :
Erreurs ESLint potentielles
Certaines méthodes accessibles sur l'objet router
retournent une Promise. Si vous avez la règle ESLint no-floating-promises activée, envisagez de la désactiver soit globalement, soit pour la ligne concernée.
Si votre application a besoin de cette règle, vous devriez soit utiliser void
avec la Promise - soit utiliser une fonction async
, await
la Promise, puis utiliser void
sur l'appel de fonction. Ceci n'est pas applicable lorsque la méthode est appelée depuis un gestionnaire onClick
.
Les méthodes concernées sont :
router.push
router.replace
router.prefetch
Solutions potentielles
withRouter
Si useRouter
ne vous convient pas, withRouter
peut aussi ajouter le même objet router
à n'importe quel composant.
Utilisation
TypeScript
Pour utiliser des composants de classe avec withRouter
, le composant doit accepter une prop router :