Gestion d’état partagé avec Context en React

L’API Context permet de transmettre des données à travers l’arborescence des composants sans avoir à passer manuellement les props à chaque niveau. Elle est particulièrement utile pour des valeurs glboales comme le thème, la langue ou l’utilisateur connecté.

Création d’un contexte

On utilise React.createContext(valeurParDefaut). L’objet retourné expose deux composants : Provider et Consumer, ainsi qu’un hook useContext pour les fonctions.

import React from 'react';

const LanguageContext = React.createContext('fr');
export const LangProvider = LanguageContext.Provider;
export const LangConsumer = LanguageContext.Consumer;
export default LanguageContext;

Le Provider

Il englobe l’arbre qui doit recevoir la valeur. Tout changement de value entraîne une mise à jour des consommateurs.

import React, { Component } from 'react';
import { LangProvider } from './LanguageContext';
import AppContent from './AppContent';
import Profile from './Profile';

class Root extends Component {
  constructor(props) {
    super(props);
    this.state = {
      language: { code: 'en', label: 'English' }
    };
  }

  render() {
    const { language } = this.state;
    return (
      <div>
        <h2>Application multilingue</h2>
        <langprovider value="{language}">
          <appcontent></appcontent>
          <profile></profile>
        </langprovider>
      </div>
    );
  }
}
export default Root;

Propriété static contextType

Dans un composant de clasce, on peut assigner static contextType = MonContexte ou définir la propriété directement sur la classe. On accède alors à la valeur via this.context.

import React, { Component } from 'react';
import LanguageContext from './LanguageContext';

class InfoPanel extends Component {
  static contextType = LanguageContext;

  render() {
    const lang = this.context;
    return (
      <div>
        <p>Langue actuelle : {lang.label}</p>
      </div>
    );
  }
}
// Alternative :
// InfoPanel.contextType = LanguageContext;
export default InfoPanel;

Hook useContext

Pour les composants fonctionnels, useContext renvoie directement la valeur du contexte fourni par le Provider le plus proche.

import React, { useContext } from 'react';
import LanguageContext from './LanguageContext';

function LanguageSelector() {
  const currentLang = useContext(LanguageContext);
  return (
    <select value="{currentLang.code}">
      <option value="fr">Français</option>
      <option value="en">English</option>
      <option value="es">Español</option>
    </select>
  );
}
export default LanguageSelector;

Le Consumer (render props)

Le Consumer attend une focntion comme enfant, qui reçoit la valeur courante du contexte.

import React from 'react';
import { LangConsumer } from './LanguageContext';

function Footer() {
  return (
    <langconsumer>
      {lang => (
        <footer>
          <p>Langue sélectionnée : {lang.label}</p>
        </footer>
      )}
    </langconsumer>
  );
}
export default Footer;

Ces quatre approches permettent d’utiliser le même contexte de manière flexible selon le type de composant (classe ou fonction) et les besoins d’encapsulation.

Étiquettes: React Context API useContext Provider Consumer

Publié le 10 octobre à 20h34