L'efficacité de useContext dans React

Par aouzou, 21 mars, 2024
Image retirée.

Introduction

Dans le développement d'applications React, la gestion de l'état global est essentielle pour partager des données entre différents composants de manière efficace. Parmi les solutions offertes par React pour cette gestion de l'état global, le Contexte est l'une des plus puissantes et des plus flexibles. Dans cet article, nous explorerons en détail l'utilisation avancée du Contexte pour la gestion de thèmes dynamiques au sein d'une application React.

Pourquoi le passage de props est problèmatique ?

Généralement, les données sont transmises d'un composant parent à un composant enfant via les props. Cependant, cette approche peut devenir laborieuse et peu pratique lorsque les données doivent traverser de nombreux composants intermédiaires, ou lorsque plusieurs composants de l'application nécessitent les mêmes informations. Le contexte permet au composant parent de rendre certaines informations disponibles à n'importe quel composant descendant, quelle que soit sa profondeur dans l'arborescence, sans avoir besoin de les transmettre explicitement via les props.

Image retirée.

 

Le contexte : une alternative efficace au passage de props 

Imaginons un scénario où nous avons une application de gestion de tâches. Cette application comporte plusieurs composants, tels que App, Header, Sidebar, TaskList, et TaskItem. Supposons que nous devons transmettre les données de l'utilisateur actuellement connecté depuis le composant App jusqu'au composant TaskItem, qui est situé plusieurs niveaux en dessous dans la hiérarchie des composants.

Sans l'utilisation du contexte, nous serions obligés de passer les données de l'utilisateur connecté via les props à travers chaque composant intermédiaire. Voici comment cela pourrait ressembler :

App.js
import React, { useState } from 'react';
import Header from './Header'; 
import Sidebar from './Sidebar'; 
import TaskList from './TaskList'; 
function App() {
  const [user, setUser] = useState({ name: 'John Doe', role: 'admin' });
  return (
   <div> 
     <Header user={user} /> 
     <Sidebar user={user} /> 
     <TaskList user={user} /> 
   </div> ); 
} 
export default App;


TaskList.js
import React from 'react'; 
import TaskItem from './TaskItem'; 
function TaskList({ user }) { 
return ( 
   <div> 
     <h2>Task List</h2> 
     <TaskItem user={user} /> 
   </div> ); } 
export default TaskList;

 

TaskItem.js
import React from 'react';

function TaskItem({ user }) {
 return (
   <div>
     <h3>Task Item</h3>
     <p>User: {user.name}</p>
   </div>
 );
}

export default TaskItem;
 

Comme vous pouvez le voir, le composant TaskItem doit recevoir les données de l'utilisateur à travers les props, bien qu'il n'en ait pas directement besoin pour son fonctionnement. Cela devient rapidement fastidieux et peu pratique à mesure que le nombre de composants intermédiaires augmente.

La même solution avec useContext 


UserContext.js
import React, { createContext, useState, useContext } from 'react';

const UserContext = createContext();

export const UserProvider = ({ children }) => {
 const [user, setUser] = useState({ name: 'John Doe', role: 'admin' });

 return (
   <UserContext.Provider value={user}>
     {children}
   </UserContext.Provider>
 );
};

export const useUser = () => useContext(UserContext);
 

App.js
import React from 'react';
import { UserProvider } from './UserContext';
import Header from './Header';
import Sidebar from './Sidebar';
import TaskList from './TaskList';

function App() {
 return (
   <UserProvider>
     <div>
       <Header />
       <Sidebar />
       <TaskList />
     </div>
   </UserProvider>
 );
}

export default App;

TaskList.js
import React from 'react';
import TaskItem from './TaskItem';
import { useUser } from './UserContext';

function TaskList() {
 const user = useUser();

 return (
   <div>
     <h2>Task List</h2>
     <TaskItem />
   </div>
 );
}

export default TaskList;

TaskItem.js
import React from 'react';
import { useUser } from './UserContext';

function TaskItem() {
 const user = useUser();

 return (
   <div>
     <h3>Task Item</h3>
     <p>User: {user.name}</p>
   </div>
 );
}

export default TaskItem;

Avec cette méthode, nous établissons un contexte utilisateur (UserContext) pour stocker les informations de l'utilisateur. Dans App.js, nous encadrons notre application avec le composant UserProvider, qui partage les données utilisateur à tous les composants enfants via ce contexte.

Dans les composants enfants comme TaskList.js et TaskItem.js, nous utilisons le hook useContext pour accéder aux données utilisateur directement depuis le contexte, évitant ainsi le besoin de les transmettre via les props. Cela simplifie grandement le processus et diminue la duplication de code.

 

Références :

  1. « Passing Data Deeply with context », React, https://react.dev/learn/passing-data-deeply-with-context, (consulté le 21 mars 2024)
  2.  Melvynx, «  Le guide complet useContext en React », https://www.youtube.com/watch?v=V13h-VKpB7Y&ab_channel=Melvynx%E2%80%A2Apprendre%C3%A0coder , (vidéo consulté le 21 mars 2024)
     

 

 

Commentaires