L'utilisation d'un Layout Component : un gain de temps considérable 

Homme devant une horloge pour symboliser l'écoulement du temps

Article écrit le 10 nov 2023 par Peter MOUNIER

Version de React-Router-DOM à cette date : 6.22.0

Temps de lecture estimé : 5min

Lorsqu'on développe une application, l'utilisation redondante de composants peut parfois s'avérer chronophage voire contre-productive. Aussi, pour éviter aux développeurs d'avoir à importer leurs composants <Header /> et <Footer /> à chaque nouvelle page, la bibliothèque React Router DOM met à leur disposition un outil très pratique : le Layout Component (composant de mise en page).

L'idée est de créer un composant qui viendra "envelopper" chacune de vos pages avec vos <Header /> et <Footer /> sans avoir à les importer.

Prenons, par exemple, la page <AboutUs /> d'un site internet. En général, son code, sans composant de mise en page, sera le suivant :

import React from 'react';
import Header from '../components/Header';
import Footer from '../components/Footer';

const AboutUs = () => {
  return (
    <>
      <Header />
      <div>Contenu de la page About us</div>
      <Footer />
    </>
  );
}

export default AboutUs;

Si on analyse ce code, on voit qu'il y a des imports <Header /> et <Footer /> et, pour CHAQUE nouvelle page, le développeur devra réitérer ces imports. Sur un site comportant des centaines de pages, cela peut vite devenir chronophage et surtout manquer d'efficacité.

React-router-DOM nous permet, via la fonction "createBrowserRouter", d'appliquer un <LayoutComponent /> aux différentes pages de sorte qu'il ne sera plus nécessaire d'importer les <Header /> et <Footer />.

Etape 1 : Création du <LayoutComponent />

Pour pouvoir appliquer ce <LayoutComponent />, il faut bien évidemment le créer. Voici un exemple :

import React from 'react';

// Importation de Outlet qui permet d'envelopper les composants enfants
import { Outlet } from "react-router-dom";

// Importation des composants qui envelopperont les différentes pages
import Header from '../components/Header';
import Footer from '../components/Footer';

// Import du css
import '../styles/layout.css'

const LayoutComponent = () => {
    return (
        <>
            <Header />
                <Outlet />
            <Footer />
        </>
    );
}

export default LayoutComponent;

C'est l'utilisation de ce <LayoutComponent /> dans la fonction "createBrowserRouter" qui permettra de l'appliquer aux différentes pages souhaitées.

Etape 2 : Utilisation dans la fonction "createBrowserRouter"

La fonction "createBrowserRouter" permet de configurer le système de routage pour l'application React et indique à l'application comment réagir aux changements d'URL. Elle sera codée dans le fichier "App.js" de l'application.

Les routes de createBrowserRouter se voient appliquer des propriétés : path, element et children.

La propriété path spécifie l'URL qui sera associée lorsqu'une route est utilisée. Il y aura, en conséquence, une route de base '/' et des sous-routes comme, par exemple, '/AboutUs'.

La propriété element détermine quel composant est rendu pour chaque route.

La propriété children contient un tableau d'objets qui définissent les sous-routes (routes enfants).

Et voici en code un exemple de la fonction createBrowserRouter :

import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import LayoutComponent from './components/LayoutComponent';
import AboutUs from './components/pages/AboutUs';

const router = createBrowserRouter([
  {
    path: '/',
    element: <LayoutComponent />, // Utilisation de Layout comme composant de mise en page
    children: [
      {
        path: 'about-us',
        element: <AboutUs />
      }
    ]
  }
]);

function App() {
  return (
    <RouterProvider router={router} />
  );
}

export default App;

La route principale se voit ainsi appliquer la mise en page du composant <LayoutComponent /> mais également ses enfants. Il n'y aura plus besoin d'effectuer des imports de <Header /> et <Footer /> dans toutes les sous-routes de cette route principale. Autrement dit, chaque fois qu'une sous-route sera rajoutée, la mise en page du composant <LayoutComponent /> viendra envelopper le composant de la page en question.

Si l'on reprend notre 1er exemple de composant <AboutUs />, voici à quoi il ressemblera avec l'utilisation de la fonction createBrowserRouter :

import React from 'react';

const AboutUs = () => {
   return (
       <div>Contenu de la page About us</div>
   );
 }

 export default AboutUs;

Et si l'on souhaitait ajouter une page "Projects" à notre application, il suffirait d'abord de créer le composant Projects puis de l'ajouter en enfant de la route principale dans notre fonction createBrowserRouter. Illustration avec ces extraits :

import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import LayoutComponent from './components/LayoutComponent';
import AboutUs from './components/pages/AboutUs';
import Projects from './components/pages/Projects';

const router = createBrowserRouter([
  {
    path: '/',
    element: <LayoutComponent />,
    children: [
      {
        path: 'about-us',
        element: <AboutUs />
      },
      {
		path: 'projects',
        element: <Projects />
      }
    ]
  }
]);

function App() {
  return (
    <RouterProvider router={router} />
  );
}

export default App;
import React from 'react';

const Projects = () => {
   return (
       <div>Contenu de la page Projet</div>
   );
 }

 export default Projects;

On constate à quel point cela est simple et compréhensible pour un éventuel développeur qui serait amené à travailler sur ce code sans avoir initialement participé au projet. Cela rend les composants plus lisibles et c'est surtout un gain de temps considérable !