[Série React Advanced] Étude de cas React Context : Mise à jour de l'état du composant parent dans le composant enfant

[Série React Advanced] Étude de cas React Context : Mise à jour de l'état du composant parent dans le composant enfant

J'ai toujours su que React Context est la méthode d'implémentation de la gestion d'état dans React, et j'ai simplement suivi le cas officiel pour exploiter le rendu à l'aide de Context, mais c'est toujours parce que l'implémentation de la méthode de mise à jour du composant parent du composant parent dans le composant enfant est trop gênant, et finalement Still a décidé d'utiliser Redux - après tout, bien que l'implémentation interne de Redux repose sur Context, elle est déjà encapsulée. Cependant, je veux encore en savoir plus sur React récemment, y compris son mécanisme de gestion d'état.Je viens d'apprendre une manière très propre d'écrire, alors j'ai écrit une note.

Contexte de base et utilisation du hook useContext

La page de mise en œuvre de base est la suivante :

thème de contexte

Deux fichiers ont été modifiés :

  • App.js

    L'essentiel est de nettoyer la page, de simplifier le rendu du contenu et d'ajouter un sous-composant :

    import {
          
           useTheme } from "./context";
    import "./styles.css";
    
    const Child = () => {
          
          
      const themeContext = useTheme();
    
      return <div style={
          
          themeContext}> "Theme" </div>;
    };
    
    export default function App() {
          
          
      return (
        <div className="App">
          <Child />
        </div>
      );
    }
    
  • contexte.js

    Il s'agit de la partie principale de l'implémentation, themeContextet encapsule simplement , de sorte que les autres composants n'ont pas besoin d'utiliser mécaniquement useContext(ThemeContext)ce code à chaque fois. L'implémentation est la suivante :

    import React, {
          
           useContext } from "react";
    
    const theme = {
          
          
      dark: {
          
          
        backgroundColor: "#333",
        color: "#ccc",
        padding: "2em",
        margin: "2em",
      },
      light: {
          
          
        backgroundColor: "#ccc",
        color: "#333",
        padding: "2em",
        margin: "2em",
      },
    };
    
    const ThemeContext = React.createContext(theme.dark);
    
    export const useTheme = () => useContext(ThemeContext);
    

Bien sûr, il s'agit d'une approche relativement paresseuse. Au lieu d'utiliser <ThemeContext.Provider value={state}> ... </ThemeContext.Provider>la méthode pour transmettre des valeurs, elle est directement écrite à mort lors de sa création.

La prochaine étape sera l'encapsulation secondaire de Context, la réalisation Provierde la pièce.

Encapsulation secondaire du contexte

Ici, un crochet personnalisé est utilisé pour encapsuler le contexte et themela valeur de est stockée dans l'état du crochet personnalisé, de sorte setStateque la valeur dans le contexte puisse être mise à jour ultérieurement à l'aide de la méthode.

Les mises à jour sont les suivantes :

  • App.js

    Seule une paire ThemeContextProviderd' .

    Il convient de noter que, comme le sous-composant est ThemeContextProviderencapsulé l'App, la valeur de ThemeContext ne peut pas être obtenue dans l'App, et seul le sous-composant "hérite" du contenu du Context.

    export default function App() {
          
          
    return (
    <ThemeContextProvider>
      <div className="App">
        <Child />
      </div>
    </ThemeContextProvider>
    );
    
  • contexte.js

    import React, {
          
           useContext, useState } from "react";
    
    // 因为变量名冲突的关系,这里将其改成了大写……不过常量大写也比较正常
    const THEME = {
          
          
      dark: {
          
          
        backgroundColor: "#333",
        color: "#ccc",
        padding: "2em",
        margin: "2em",
      },
      light: {
          
          
        backgroundColor: "#ccc",
        color: "#333",
        padding: "2em",
        margin: "2em",
      },
    };
    
    const ThemeContext = React.createContext();
    
    export const useTheme = () => useContext(ThemeContext);
    
    export const ThemeContextProvider = ({
           
            children }) => {
          
          
      const [theme, setTheme] = useState(THEME.dark);
    
      return (
        <ThemeContext.Provider value={
          
          theme}>{
          
          children}</ThemeContext.Provider>
      );
    };
    

    Tout ce que nous avons à faire après cela est de passer setThemecette méthode au composant enfant.

    Étant donné que Context ne peut transmettre qu'une seule valeur, la méthode adoptée ici consiste à créer à nouveau un nouveau Context, dont la valeur est de mettre à jour la fonction set dans le crochet cuttom.

Contexte de mise à jour ajouté

Cette étape équivaut à encapsuler le contexte trois fois. Les modifications spécifiques sont les suivantes :

// 之前的THEME没有变化

const ThemeContext = React.createContext();
const ThemeUpdateContext = React.createContext();

export const useTheme = () => useContext(ThemeContext);
export const useThemeUpdate = () => useContext(ThemeUpdateContext);

export const ThemeContextProvider = ({
     
      children }) => {
    
    
  const [theme, setTheme] = useState(THEME.dark);

  const updateTheme = ({
     
      theme }) => {
    
    
    // 这里只是做一个传值的示范
    console.log(theme);

    setTheme((prevTheme) =>
      prevTheme === THEME.dark ? THEME.light : THEME.dark
    );
  };

  return (
    <ThemeContext.Provider value={
    
    theme}>
      <ThemeUpdateContext.Provider value={
    
    updateTheme}>
        {
    
    children}
      </ThemeUpdateContext.Provider>
    </ThemeContext.Provider>
  );
};

Utilisez useThemeUpdate pour changer l'état du contexte

La mise à jour dans App.js est la suivante :

const Child = () => {
    
    
  const themeContext = useTheme();
  const updateTheme = useThemeUpdate();

  return (
    <div
      style={
    
    themeContext}
      onClick={
    
    () => updateTheme({
    
     theme: "hello world" })}
    >
      "Theme"
    </div>
  );
};

On peut voir que la logique de mise à jour est relativement claire et l'effet final de la mise en œuvre est le suivant :

contexte complet

De ce point de vue, si la structure du projet est relativement simple et que la demande pour Redux-Saga n'est pas très importante, il peut être judicieux d'utiliser directement le crochet de contexte.Après tout, les crochets évitent le processus compliqué d' Context.Consumerutilisation des fonctions de rappel pour obtenir des valeurs. . Après avoir encapsulé le contexte trois fois, vous pouvez directement utiliser const someVar = useXXX();la méthode pour obtenir la valeur, et const updateSomeVar = useXXXUpdate();la méthode pour la mettre à jour ne sera pas trop compliquée.

Enfin, si vous souhaitez enregistrer une couche de wrapper, vous pouvez également utiliser cette méthode :

<ThemeContext.Provider value={
    
    {
    
     theme, updateTheme }}>
  {
    
    children}
</ThemeContext.Provider value={
    
    {
    
     theme, updateTheme }}>

// when you need to use it
const {
    
    theme, updateTheme } = useTheme();

Cependant, c'est aussi une tendance personnelle, et je ne me soucie pas des détails des fautes de frappe et des invites d'importation automatiques.Après tout, la plupart du temps, je pense toujours qu'il est plus pratique d'avoir des invites automatiques/importation automatique.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_42938619/article/details/124122194
conseillé
Classement