5
Module 5
Routage client et changement de page
A la fin de ce cinquième module, l'étudiant devra être capable d'utiliser le routage client pour simuler plusieurs pages dans un site web.

Le routage client
Next.js offre plusieurs types de routage pour gérer la navigation dans une application. Dans cette section, nous ferons une briève description de ces types de routage mais nous appliquerons juste deux sur notre application 'biblio-app'. À savoir : 'le routage basé sur les Liens (<Link>)' et 'le routage Client-Side avec next/router'.

le routage basé sur les Liens (<Link>)
Next.js utilise un composant Link pour créer des liens internes qui permettent la navigation client-side. Contrairement à des liens HTML classiques qui déclenchent un rechargement complet, le composant Link permet une navigation fluide sans rechargement. Pour matérialiser, nous allons complètement changer l'organisation de notre application 'blio-app', à partir de sa dernière version (celle obtenue dans le module4).
Réorgisation de la structure de l'application
Ci-dessous les actions à mener :
Nouveaux dossiers : Dans le dossier 'app', créer un dossier correspondant à chaque menu (Le dossier doit porter le nom du menu) de notre application, puis créer un fichier 'page.jsx' à l'intérieur du nouveau dossier. Nous aurons donc trois nouveaux dossiers ('documents', 'contact' et 'connexion'), chacun contenant un fichier 'page.jsx'
Supprimer la variable 'page' de 'layout.jsx' : Supprimer la ligne 'const [page, setPage] = useState('accueil');
Supprimer 'setPage={setPage}' de 'layout.jsx'
Remplacer tout le contenu de '<main>' par '{children}'
Ci-dessous, le nouveau contenu de 'layout.jsx'
/app/layout.jsx
'use client'
import Header from '@/components/Header'
import { Inter } from 'next/font/google';
import Footer from '@/components/Footer';
import './globals.css';
import styles from './layout.module.css';
const inter = Inter({ subsets: ['latin'] });
export default function RootLayout({ children }) {
  return (
    <html lang='en'>
      <body className={inter.className + ' ' + styles.body}>
        <Header />
        <main className={styles.main}>
          {children}
        </main>
        <Footer />
      </body>
    </html>
  );
}
Modifier '/app/page.jsx' : Etant donné que 'page.jsx' joue le rôle du fichier 'index' habituel, il recevra donc le composant 'Accueil'. Son nouveau code est le suivant:
/app/page.jsx
'use client'
import Accueil from '@/components/Accueil';
export default function Home() {
  return <>
    <Accueil />
  </>;
}
Code de '/app/connexion/page.jsx' : Importer le composant 'Connexion' dans le fichier 'page.jsx' se trouvant dans le dossier 'connexion' nouvellement créé :
/app/connexion/page.jsx
import Connexion from '@/components/Connexion';
export default function Page() {
    return <>
        <Connexion />
    </>;
}
Code de '/app/contact/page.jsx' : Importer le composant 'Contact' dans le fichier 'page.jsx' se trouvant dans le dossier 'contact' nouvellement créé :
/app/contact/page.jsx
import Contact from '@/components/Contact';
export default function Page() {
    return <>
        <Contact />
    </>;
}
Code de '/app/documents/page.jsx' : Importer le composant 'Documents' dans le fichier 'page.jsx' se trouvant dans le dossier 'documents' nouvellement créé :
/app/documents/page.jsx
'use client'
import Documents from '@/components/Documents';
export default function Page() {
    return <>
        <Documents />
    </>;
}
Nouveau code de '/Components/MenuNav.jsx' : Toutes les pages étant déjà créées, il est temps de mettre les liens vers elles à partir du composant 'MenuNav'. Pour cela, il faut remplacer le code du composant 'MenuNav' par le code ci-dessous :
/Components/MenuNav.jsx
import Link from 'next/link';
import styles from './MenuNav.module.css';
export default function MenuNav() {
    return <nav className={styles.nav}>
        <ul>
            <li><Link href='/'>Accueil</Link></li>
            <li><Link href='/documents'>Documents</Link></li>
            <li><Link href='/contact'>Contact</Link></li>
            <li><Link href='/connexion'>Connexion</Link></li>
        </ul>
    </nav>;
}
Remarque
Il est important de noter qu'un nouveau composant de Next a été importer dans le composant 'MenuNav' : il s'agit du composant 'Link'. De plus, la balise '<a>' a été remplacée par ce nouveau Composant.
Importance du composant 'Link'
Le composant Link dans Next.js joue un rôle crucial dans le routage côté client, permettant une navigation fluide et rapide entre différentes pages de l'application sans recharger entièrement la page. Parmi ses fonctionnalités, on peut citer :
Le préchargement de pages : Next.js précharge automatiquement les pages liées via le composant Link. Lorsque le lien apparaît à l'écran (ou lorsqu'il est anticipé par un certain comportement utilisateur), Next.js peut précharger la page associée en arrière-plan. Cela rend la navigation presque instantanée lorsqu'un utilisateur clique sur le lien.
La navigation sans rechargement complet : Lorsqu'un utilisateur clique sur un lien standard <a>, le navigateur déclenche un rechargement complet de la page. Avec le composant Link, Next.js utilise le routage côté client, ce qui permet de charger uniquement le contenu nécessaire sans rechargement complet. Cela améliore les performances et l'expérience utilisateur.
Exercice d'application
Remplacer le composant 'Link' par la balise standard 'a', ensuite effectuer des changements de page et essayer de trouver la différence.
Bon à savoir
Il n'est pas nécessaire d'utiliser le composant Link pour un lien externe à l'application. Dans ce cas, il vaut mieux utiliser la balise standard 'a'.

le routage Client-Side avec le hook useRouter
Le hook useRouter de Next.js permet d'accéder au routeur (router) et d'interagir avec le routage côté client. Avec useRouter, nous pouvons obtenir des informations sur la route actuelle, naviguer entre les pages, ou même réagir aux événements de routage. Voici quelques-unes des fonctionnalités principales du hook useRouter :
Récupération des informations de la route actuelle
useRouter permet d'accéder à des détails comme le chemin actuel (pathname), les paramètres de requête (query), et la chaîne de recherche (asPath).
Navigation conditionnelle
On peut utiliser useRouter pour naviguer entre les pages de manière conditionnelle, avec des fonctions comme router.push() ou router.replace(). Cela est utile pour des redirections ou des transitions conditionnelles.
Gestion des événements de routage
useRouter permet d'écouter des événements de routage, comme le début du changement de route, l'achèvement, ou les erreurs, en utilisant des méthodes comme router.events.on().
Illustration de useRouter
Pour illustrer le fonctionnement de 'useRouter', nous allons récrire notre 'MenuNav.jsx' en l'utilisant. Le nouveau code est le suivant :
/Components/MenuNav.jsx
import styles from './MenuNav.module.css';
import { useRouter } from 'next/navigation';
export default function MenuNav() {
    const routeur = useRouter();
    return <nav className={styles.nav}>
        <ul>
            <li onClick={() => routeur.push('/')}>Accueil</li>
            <li onClick={() => routeur.push('/documents')}>Documents</li>
            <li onClick={() => routeur.push('/contact')}>Contact</li>
            <li onClick={() => routeur.push('/connexion')}>Connexion</li>
        </ul>
    </nav>;
}
Remarque
Comme nous pouvons le constater, le hook 'useRouter' a été importé et utilisé pour faire la redirection de page en cas de clic sur un lien du menu de navigation.
Bon à savoir
Il est recommandé d'utliser 'useRouter' seulement lorsqu'on ne peut utliser le composant 'Link'.

Code source
Important
Avant d'executer la commande 'npm run dev', bien vouloir exécuter la commande 'npm i'.

Travail à faire