React State

React Context API

L'API Context est la méthode native de React pour partager un état à travers un arbre de composants sans passer par les props à chaque niveau. Bien utilisée, elle élimine le prop drilling ; utilisée sans précaution, elle provoque des re-renders globaux.

intermediate13 min readUpdated 15 sept. 2026
ThemeContext.jsx
jsx
// ThemeContext.jsx
import { createContext, useContext } from "react";

const ThemeContext = createContext("light");

export function useTheme() {
  return useContext(ThemeContext);
}

export function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}
Inclus dans
React
Packages additionnels
Aucun
Créé avec
createContext
Fourni par
Context.Provider
Lu avec
useContext
Idéal pour
Valeurs partagées à faible fréquence de mise à jour

Pourquoi c'est important

Pourquoi Context existe

Plus de prop drilling

N'importe quel composant de l'arbre peut lire une valeur partagée directement, peu importe sa profondeur d'imbrication.

Zéro dépendance

Context fait partie de React, il n'y a donc rien à installer et aucun runtime supplémentaire à gérer.

Providers composables

Vous pouvez imbriquer plusieurs providers et diviser une valeur volumineuse en contextes ciblés pour de meilleures performances.

Le tableau complet

Les trois piliers de Context

Un objet de contexte, un provider qui fournit une valeur, et un hook qui la lit. Il n'y a rien d'autre à apprendre.

L'objet de contexte

Identité

Créé une seule fois avec createContext, c'est la clé que les composants utilisent pour trouver un provider.

Le provider

Fourniture

Un composant qui injecte une valeur dans l'arbre et déclenche le re-render des consommateurs lorsqu'elle change.

Le consommateur

Lecture

useContext lit la valeur du provider le plus proche, et un hook personnalisé encapsule souvent cela pour plus de commodité.

Context en un coup d'œil

Le cœur de Context

createContext

Définit un contexte avec une valeur par défaut utilisée lorsqu'aucun provider n'est présent.

Provider

Enveloppe un sous-arbre et transmet la valeur actuelle à tous les consommateurs en dessous.

useContext

Lit la valeur du provider le plus proche à l'intérieur de n'importe quel composant.

Hooks personnalisés

Encapsule useContext dans un hook pour offrir une API claire et des vérifications d'erreurs aux appelants.

Division des contextes

Sépare l'état et les actions pour que les consommateurs ne re-rendernt que pour ce qu'ils utilisent.

Performance

Context re-render tous les consommateurs lors d'un changement ; gardez donc vos valeurs stables et ciblées.

Un bref aperçu

D'une API cachée à une fonctionnalité de premier plan

  1. 2018

    Context devient stable

    React 16.3 introduit une API Context supportée après plusieurs années de version expérimentale.

    18
  2. 2019

    Arrivée des Hooks

    useContext permet de consommer un contexte en une seule ligne et remplace les render props.

    19
  3. 2021

    Context et performance

    La communauté adopte la division des contextes et la mémoïsation des valeurs comme meilleures pratiques.

    21
  4. Aujourd'hui

    Un outil intégré

    Context est le choix par défaut pour les thèmes, l'auth et la locale, tandis que les stores gèrent les états à haute fréquence.

    Aujourd'hui

Le guide complet

React Context API: Tout ce que vous devez savoir

Qu’est-ce que l’API Context ?

L’API Context est la méthode intégrée à React pour transmettre des données à travers un arbre de composants sans avoir à faire passer des props à chaque niveau. Elle résout un problème courant et spécifique : une valeur dont de nombreux composants ont besoin, mais qui se situe très haut dans l’arbre.

L’exemple classique est le thémage. Un Button situé profondément dans l’arbre a besoin du thème actuel, mais chaque composant entre le sommet et le bouton devrait accepter et transmettre une prop theme. C’est ce qu’on appelle le prop drilling, et Context permet de l’éviter. Vous fournissez la valeur une seule fois, et n’importe quel descendant peut la lire directement.

Création et fourniture du contexte

Le contexte se compose de trois éléments : un objet, un provider et un hook de consommation.

// AuthContext.jsx
import { createContext, useContext, useMemo, useState } from "react";

const AuthContext = createContext(null);

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);

  const value = useMemo(
    () => ({
      user,
      login: (nextUser) => setUser(nextUser),
      logout: () => setUser(null),
    }),
    [user],
  );

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error("useAuth must be used within an AuthProvider");
  }
  return context;
}

createContext définit le contexte ainsi qu’une valeur par défaut. Le provider fournit la valeur actuelle à tous les composants enfants. Le hook personnalisé lit cette valeur et renvoie une erreur explicite si le composant est utilisé en dehors du provider.

Consommer le contexte

N’importe quel descendant peut lire la valeur, peu importe sa profondeur dans l’arborescence.

// Header.jsx
import { useAuth } from "./AuthContext";

export function Header() {
  const { user, logout } = useAuth();

  return (
    <header>
      <span>{user ? `Hi, ${user.name}` : "Guest"}</span>
      {user && <button onClick={logout}>Sign out</button>}
    </header>
  );
}

Le Header n’a jamais reçu de prop de la part de App. Il est allé chercher la valeur dont il avait besoin directement dans l’arbre, ce qui permet aux composants intermédiaires de ne pas être au courant des données qu’ils n’utilisent pas.

Le contexte n’est pas un état

Cette distinction induit souvent en erreur. Le contexte ne détient pas d’état et ne gère pas les mises à jour. Il transporte une valeur. L’état lui-même réside dans useState ou useReducer, et le provider le transmet aux composants enfants.

C’est pourquoi un pattern courant consiste à coupler le contexte avec un reducer :

// CartContext.jsx
import { createContext, useContext, useReducer } from "react";

const CartContext = createContext(null);

function reducer(state, action) {
  switch (action.type) {
    case "add":
      return [...state, action.item];
    case "remove":
      return state.filter((item) => item.id !== action.id);
    default:
      return state;
  }
}

export function CartProvider({ children }) {
  const [items, dispatch] = useReducer(reducer, []);
  return (
    <CartContext.Provider value={{ items, dispatch }}>
      {children}
    </CartContext.Provider>
  );
}

export const useCart = () => useContext(CartContext);

Le reducer rend les mises à jour prévisibles, et le contexte les rend accessibles partout sans avoir recours au prop drilling.

Performance : la véritable contrainte

Lorsqu’une valeur de provider change, chaque composant qui lit ce contexte est re-rendu. Il n’existe pas de sélecteur, vous ne pouvez donc pas vous abonner à une seule partie de la valeur. Deux bonnes pratiques permettent de garder cela gérable.

Mémorisez la valeur. Un littéral d’objet crée une nouvelle référence à chaque rendu, ce qui signifie que chaque consommateur est re-rendu même lorsque rien n’a changé.

// memoised
const value = useMemo(() => ({ user, logout }), [user]);

Séparez les contextes. Placez l’état et les actions dans des contextes distincts, ou séparez-les par fonctionnalité, afin qu’un composant ayant seulement besoin de dispatcher une action ne soit pas re-rendu lors d’un changement d’état.

// split.jsx
const CartStateContext = createContext(null);
const CartActionsContext = createContext(null);

Les composants qui appellent uniquement des actions s’abonnent au contexte des actions, dont l’identité ne change jamais ; ils ne sont donc jamais re-rendus suite à une mise à jour de l’état. Cette simple astuce résout la plupart des problèmes de performance liés au contexte.

Quand utiliser Context, et quand l’éviter

Context est l’outil idéal pour :

  • Le thème et le mode de couleur.
  • L’utilisateur authentifié et la session.
  • La locale et les traductions.
  • Un routeur ou une petite configuration stable.

Tournez-vous vers un store dédié lorsque vous avez :

  • Des mises à jour fréquentes, comme la saisie de texte, le glisser-déposer ou des animations.
  • Un arbre d’état volumineux où les composants nécessitent des selectors.
  • Un besoin de middleware, de persistance ou d’outils de développement de type “time-travel”.
  • Un état serveur qui nécessite du caching et du refetching.

Des bibliothèques comme Zustand et Redux Toolkit ajoutent des selectors pour que les composants s’abonnent à des tranches (slices) plutôt qu’à la valeur complète. Pour les données serveur, TanStack Query gère entièrement le caching.

Bonnes pratiques

  • Enveloppez useContext dans un hook personnalisé et vérifiez l’absence de provider.
  • Mémoïsez les valeurs du provider avec useMemo.
  • Séparez les contextes par responsabilité, en particulier l’état par rapport aux actions.
  • Gardez des valeurs de contexte restreintes et ciblées.
  • Utilisez useReducer lorsque les mises à jour sont complexes ou dépendent de l’état précédent.
  • N’utilisez pas le contexte pour des mises à jour fréquentes ; utilisez un store basé sur des sélecteurs.
  • Fournissez des valeurs par défaut cohérentes pour que les composants puissent s’afficher en dehors d’un provider lorsque c’est approprié.

Erreurs courantes

  • Traiter le context comme un gestionnaire d’état et s’attendre à avoir des selectors.
  • Passer un objet inline comme valeur du provider, provoquant le re-render de tout l’arbre.
  • Regrouper des données sans rapport dans un seul context géant.
  • Oublier la valeur par défaut et provoquer un crash sur undefined.
  • Utiliser le context pour des valeurs dont seuls un ou deux composants ont besoin.
  • S’attendre à ce que le context optimise automatiquement les re-renders.

Et après ?

Le Context est le fondement du partage d’état dans React, et connaître ses limites vous permet de savoir quand passer à l’étape supérieure. Comparez-le avec Redux Toolkit pour un état prévisible à grande échelle et Zustand pour un store basé sur des sélecteurs et plus léger, puis gérez vos données serveur avec TanStack Query. Pour Vue, le concept équivalent est abordé dans le guide Pinia.

Partage d'une valeur

Context est destiné aux valeurs dont beaucoup de composants ont besoin, comme le thème ou l'utilisateur actuel. Ce n'est pas un remplacement pour chaque prop.

Préférer
const ThemeContext = createContext("light");

function Button() {
  const theme = useContext(ThemeContext);
  return <button className={theme} />;
}
Éviter
function Button({ theme }) {
  return <button className={theme} />;
}
// drilled through every
// level of the tree

Fourniture d'une valeur

Un objet créé en ligne génère une nouvelle référence à chaque render, provoquant le re-render de chaque consommateur. Mémoïsez-le.

Préférer
const value = useMemo(
  () => ({ user, logout }),
  [user],
);

<AuthContext.Provider value={value}>
  {children}
</AuthContext.Provider>
Éviter
<AuthContext.Provider
  value={{ user, logout }}
>
  {children}
</AuthContext.Provider>

FAQ

Foire aux questions

Keep learning

Related topics from the roadmap.

$ commencer à apprendre

Prêt à apprendre Context API ?

Notre tutoriel interactif vous guide à travers Context API pas à pas — avec des quiz et du vrai code que vous pouvez exécuter dans le navigateur.