recherche
Maisoninterface Webjs tutorieluseCustomReducer Hook : un outil de gestion d'état polyvalent

useCustomReducer Hook: A Versatile State Management Tool

Introduction

La gestion de l'état dans React peut être délicate, en particulier lorsqu'il s'agit de structures d'état complexes ou imbriquées. Pour simplifier cela, le hook useCustomReducer combine la puissance de useReducer avec une API flexible pour mettre à jour l'état de manière propre et déclarative. Ce hook prend en charge les états primitifs, imbriqués et matriciels, ce qui le rend adapté à un large éventail de cas d'utilisation.

Dans cet article, nous explorerons le hook useCustomReducer et ses méthodes de base pour gérer l'état dans les applications React. Nous aborderons la définition du hook, ses signatures de méthode et des exemples d'utilisation détaillés pour différents types de structures d'état. À la fin, vous aurez une solide compréhension de la façon d'utiliser le hook useCustomReducer pour gérer les états complexes dans vos composants React.

 Table des matières

  • Présentation
  • Table des matières
  • Aperçu des crochets
  • Exemple de composant React
  • Caractéristiques
  • Définition
    • Définitions des méthodes
  • Exemples d'utilisation détaillés
    • Gérer les primitives
    • Gestion des données du formulaire
    • Gestion des tableaux
    • Gestion de l'état imbriqué
  • Pourquoi utiliser useCustomReducer ?
  • Conclusion
  • Ressources supplémentaires

Présentation des crochets

Le hook useCustomReducer est un hook React personnalisé qui fournit un moyen simple et flexible de gérer des structures d'état complexes. Il combine les avantages de useReducer avec une API propre pour mettre à jour les valeurs d'état. Ce hook est conçu pour gérer différents types d'état, notamment les valeurs primitives, les objets, les tableaux et les structures de données imbriquées.

Voici un aperçu du hook useCustomReducer :

  • Méthodes de base :

    • set : Mettez à jour les valeurs d'état directement ou via une fonction de rappel.
    • réinitialiser : rétablir l'état à sa valeur initiale.
    • fusionner : fusionner les mises à jour partielles dans l'état existant.
  • Structures d'état : - Prend en charge les valeurs primitives (par exemple, les nombres, les chaînes, les booléens). - Gère les structures d'état basées sur les objets (par exemple, les données de formulaire, les profils utilisateur). - Gère les structures d'état basées sur des tableaux (par exemple, listes, collections).

  • Type-Safe : - Entièrement tapé à l'aide de TypeScript pour un développement fiable et une prévention des erreurs.

  • API simple : - Fournit des méthodes intuitives pour mettre à jour, réinitialiser et fusionner les valeurs d'état. - Prend en charge les mises à jour directes et les fonctions de rappel pour les changements d'état dynamiques.

import { useReducer, useCallback, useMemo } from "react";

type Primitive = boolean | string | number | Date | null | undefined;
type NestedObject = { [key: string]: Primitive | NestedObject | NestedArray };
type NestedArray = Array<primitive nestedobject>;

type State = Primitive | NestedObject | NestedArray;

type Action<t> =
  | { type: "SET"; payload: Partial<t> | ((prevState: T) => Partial<t>) }
  | { type: "RESET"; payload?: T }
  | { type: "MERGE"; payload: Partial<t> };

function useCustomReducer<t extends state>(initialState: T) {
  const reducer = useCallback(
    (state: T, action: Action<t>): T => {
      switch (action.type) {
        case "SET":
          const newPayload =
            typeof action.payload === "function"
              ? action.payload(state)
              : action.payload;
          if (newPayload instanceof Date) {
            return newPayload as T;
          }
          if (
            typeof state === "object" &&
            !Array.isArray(state) &&
            state !== null
          ) {
            return { ...state, ...newPayload };
          }
          return newPayload as T;
        case "RESET":
          return action.payload ?? initialState;
        case "MERGE":
          if (
            typeof state === "object" &&
            !Array.isArray(state) &&
            state !== null
          ) {
            return { ...state, ...action.payload };
          }
          return action.payload as T;
        default:
          throw new Error("Invalid action type");
      }
    },
    [initialState]
  );

  const [state, dispatch] = useReducer(reducer, initialState);

  const set = useCallback(
    (payload: Partial<t> | ((prevState: T) => Partial<t>)) =>
      dispatch({ type: "SET", payload }),
    []
  );
  const reset = useCallback(
    (payload?: T) => dispatch({ type: "RESET", payload }),
    []
  );
  const merge = useCallback(
    (payload: Partial<t>) => dispatch({ type: "MERGE", payload }),
    []
  );

  const memoizedState = useMemo(() => state, [state]);

  return [memoizedState, { set, reset, merge }] as const;
}

export default useCustomReducer;
</t></t></t></t></t></t></t></t></t></primitive>

Le hook useCustomReducer est implémenté à l’aide du hook useReducer de React. Il définit une fonction de réduction personnalisée qui gère différents types d'actions pour mettre à jour, réinitialiser ou fusionner les valeurs d'état. Le hook fournit trois méthodes principales définies, réinitialisées et fusionnées pour interagir avec l'état. La méthode set peut accepter soit un objet avec de nouvelles valeurs d'état, soit une fonction de rappel pour calculer l'état suivant. La méthode de réinitialisation ramène l'état à sa valeur initiale, tandis que la méthode de fusion fusionne les mises à jour partielles dans l'état existant.

Exemple de composant React

Voici un exemple d'utilisation du hook useCustomReducer dans un composant React pour gérer un état de compteur simple :

import useCustomReducer from "./use-custom-reducer";
import { faker } from "@faker-js/faker";
import { Button } from "@/components/ui/button";

export default function Use() {
  const [formValues, { set, reset, merge }] = useCustomReducer({
    name: faker.person.firstName(),
    age: faker.number.int({ min: 18, max: 99 }),
    address: {
      street: faker.location.streetAddress(),
      city: faker.location.city(),
      state: faker.location.state(),
      zip: faker.location.zipCode(),
    },
    hobbies: [faker.person.bio(), faker.person.bio(), faker.person.bio()],
  });

  const [bool, { set: setBool }] = useCustomReducer<boolean>(
    faker.datatype.boolean()
  );
  const [num, { set: setNum }] = useCustomReducer(faker.number.int());
  const [str, { set: setStr }] = useCustomReducer<string>(faker.lorem.word());
  const [date, { set: setDate }] = useCustomReducer(faker.date.recent());
  const [nil, { set: setNil }] = useCustomReducer(null);
  const [undef, { set: setUndef }] = useCustomReducer(undefined);
  const [arr, { set: setArr }] = useCustomReducer([
    faker.number.int(),
    faker.number.int(),
    faker.number.int(),
  ]);
  const [nestedArr, { set: setNestedArr }] = useCustomReducer([
    faker.number.int(),
    faker.lorem.word(),
    { three: faker.number.float() },
  ]);

  const [obj, { set: setObj }] = useCustomReducer({
    a: faker.number.int(),
    b: faker.number.int(),
    c: faker.number.int(),
  });
  const [nestedObj, { set: setNestedObj }] = useCustomReducer({
    a: faker.number.int(),
    b: faker.lorem.word(),
    c: { three: faker.number.float() },
  });

  return (
    <div classname="p-4 space-y-6">
      <h1 id="Use">Use</h1>
      <div classname="space-x-2 space-y-2">
        <h2 id="Form-Values">Form Values</h2>
        <p classname="text-gray-500">{JSON.stringify(formValues)}</p>
        <button onclick="{()"> set({ name: faker.person.firstName() })}>
          Set Name
        </button>
        <button onclick="{()"> set((prevState) => ({ age: prevState.age - 1 }))}
        >
          Decrement Age
        </button>
        <button onclick="{()"> set((prevState) => ({ age: prevState.age + 1 }))}
        >
          Increment Age
        </button>
        <button onclick="{()">
            set((prevState) => ({
              address: {
                ...prevState.address,
                street: faker.location.streetAddress(),
              },
            }))
          }
        >
          Set Street
        </button>
        <button onclick="{()"> reset()}>Reset</button>
        <button onclick="{()"> merge({ age: faker.number.int({ min: 18, max: 99 }) })}
        >
          Merge
        </button>
      </div>
      <hr classname="border-t border-gray-300">
      <div classname="space-x-2 space-y-2">
        <h2 id="Boolean-Value">Boolean Value</h2>
        <p classname="text-gray-500">{bool.toString()}</p>
        <button onclick="{()"> setBool(faker.datatype.boolean())}>
          Set Bool
        </button>
      </div>
      <hr classname="border-t border-gray-300">
      <div classname="space-x-2 space-y-2">
        <h2 id="Number-Value">Number Value</h2>
        <p classname="text-gray-500">{num.toString()}</p>
        <button onclick="{()"> setNum(faker.number.int())}>Set Num</button>
      </div>
      <hr classname="border-t border-gray-300">
      <div classname="space-x-2 space-y-2">
        <h2 id="String-Value">String Value</h2>
        <p classname="text-gray-500">{str}</p>
        <button onclick="{()"> setStr(faker.lorem.word())}>Set Str</button>
      </div>
      <hr classname="border-t border-gray-300">
      <div classname="space-x-2 space-y-2">
        <h2 id="Date-Value">Date Value</h2>
        <p classname="text-gray-500">{JSON.stringify(date)}</p>
        <button onclick="{()"> setDate(faker.date.recent())}>Set Date</button>
        <button onclick="{()"> setDate(new Date("2022-01-01"))}>
          Set Date to 2022
        </button>
      </div>
      <hr classname="border-t border-gray-300">
      <div classname="space-x-2 space-y-2">
        <h2 id="Nil-and-Undefined">Nil and Undefined</h2>
        <p classname="text-gray-500">{String(nil)}</p>
        <button onclick="{()"> setNil(null)}>Set Nil</button>
        <p classname="text-gray-500">{String(undef)}</p>
        <button onclick="{()"> setUndef(undefined)}>Set Undef</button>
      </div>
      <hr classname="border-t border-gray-300">
      <div classname="space-x-2 space-y-2">
        <h2 id="Array-Value">Array Value</h2>
        <p classname="text-gray-500">{arr.toString()}</p>
        <button onclick="{()">
            setArr([faker.number.int(), faker.number.int(), faker.number.int()])
          }
        >
          Set Arr
        </button>
      </div>
      <hr classname="border-t border-gray-300">
      <div classname="space-x-2 space-y-2">
        <h2 id="Nested-Array">Nested Array</h2>
        <p classname="text-gray-500">{JSON.stringify(nestedArr)}</p>
        <button onclick="{()">
            setNestedArr([
              faker.number.int(),
              faker.lorem.word(),
              { three: faker.number.float() },
            ])
          }
        >
          Set Nested Arr
        </button>
      </div>
      <hr classname="border-t border-gray-300">
      <div classname="space-x-2 space-y-2">
        <h2 id="Object-Value">Object Value</h2>
        <p classname="text-gray-500">{JSON.stringify(obj)}</p>
        <button onclick="{()">
            setObj({
              a: faker.number.int(),
              b: faker.number.int(),
              c: faker.number.int(),
            })
          }
        >
          Set Obj
        </button>
      </div>
      <hr classname="border-t border-gray-300">
      <div classname="space-x-2 space-y-2">
        <h2 id="Nested-Object">Nested Object</h2>
        <p classname="text-gray-500">{JSON.stringify(nestedObj)}</p>
        <button onclick="{()">
            setNestedObj({
              a: faker.number.int(),
              b: faker.lorem.word(),
              c: { three: faker.number.float() },
            })
          }
        >
          Set Nested Obj
        </button>
      </div>
    </div>
  );
}
</string></boolean>

Caractéristiques

  • Prend en charge diverses structures d'état : gère les primitives, les objets, les tableaux et les structures de données imbriquées.

  • API simple :

    • set : Mettez à jour les valeurs d'état directement ou via un rappel.
    • réinitialiser : rétablir l'état à sa valeur initiale.
    • fusionner : fusionner les mises à jour partielles dans l'état existant.
  • Type-Safe : entièrement typé à l'aide de TypeScript pour un développement fiable.

Définition

Le hook useCustomReducer est un hook React personnalisé pour gérer un état complexe. Il fournit trois méthodes principales : définir, réinitialiser et fusionner pour gérer les structures d'état primitives, imbriquées et basées sur des tableaux. Voici une description du hook et de ses méthodes :

function useCustomReducer<t extends state>(
  initialState: T
): [
  T,
  {
    set: (payload: Partial<t> | ((prevState: T) => Partial<t>)) => void;
    reset: (payload?: T) => void;
    merge: (payload: Partial<t>) => void;
  }
];
</t></t></t></t>

Définitions des méthodes

  • ensemble
    • Mise à jour l'état en remplaçant ou en mettant à jour partiellement ses propriétés.
    • Accepte soit :
    • Un objet avec de nouvelles valeurs d'état.
    • Une fonction de rappel (prevState) => Partiel pour calculer l'état suivant.

Exemple

const [state, { set }] = useCustomReducer({ count: 0 });

set((prevState) => ({ count: prevState.count + 1 }));
  • réinitialiser
    • Réinitialise l'état à l'état initial ou à une valeur spécifiée.
    • Accepte une charge utile facultative pour remplacer l'état initial.

Exemple

reset(); // Resets to initial state.

reset({ name: "John", age: 25 }); // Resets to a new state.
  • fusionner
    • Fusionne les mises à jour partielles dans l'état existant.
    • Accepte un objet avec des mises à jour d'état partielles.
    • Fonctionne uniquement pour les objets et les structures d'état imbriquées.

Exemple

merge({ city: "New York" }); // Adds or updates the 'city' field.

Exemples d'utilisation détaillés

Le hook useCustomReducer est polyvalent et peut être utilisé pour gérer différents types de structures étatiques. Voici quelques exemples pour démontrer son utilisation avec différents types d'état :

 Gestion des primitives

  • Numéro :
const initialState = 0;

const [count, { set, reset }] = useCustomReducer(initialState);
  • Utilisation :

    • Incrémentez le nombre :
    set((prevState) => prevState + 1);
    
    • Réinitialiser à l'état initial :
    reset();
    
    • Définissez une nouvelle valeur :
      set(10);
    
  • Chaîne :

const initialState = "Hello, World!";

const [message, { set, reset }] = useCustomReducer(initialState);
  • Utilisation :

    • Mettre à jour la chaîne :
    import { useReducer, useCallback, useMemo } from "react";
    
    type Primitive = boolean | string | number | Date | null | undefined;
    type NestedObject = { [key: string]: Primitive | NestedObject | NestedArray };
    type NestedArray = Array<primitive nestedobject>;
    
    type State = Primitive | NestedObject | NestedArray;
    
    type Action<t> =
      | { type: "SET"; payload: Partial<t> | ((prevState: T) => Partial<t>) }
      | { type: "RESET"; payload?: T }
      | { type: "MERGE"; payload: Partial<t> };
    
    function useCustomReducer<t extends state>(initialState: T) {
      const reducer = useCallback(
        (state: T, action: Action<t>): T => {
          switch (action.type) {
            case "SET":
              const newPayload =
                typeof action.payload === "function"
                  ? action.payload(state)
                  : action.payload;
              if (newPayload instanceof Date) {
                return newPayload as T;
              }
              if (
                typeof state === "object" &&
                !Array.isArray(state) &&
                state !== null
              ) {
                return { ...state, ...newPayload };
              }
              return newPayload as T;
            case "RESET":
              return action.payload ?? initialState;
            case "MERGE":
              if (
                typeof state === "object" &&
                !Array.isArray(state) &&
                state !== null
              ) {
                return { ...state, ...action.payload };
              }
              return action.payload as T;
            default:
              throw new Error("Invalid action type");
          }
        },
        [initialState]
      );
    
      const [state, dispatch] = useReducer(reducer, initialState);
    
      const set = useCallback(
        (payload: Partial<t> | ((prevState: T) => Partial<t>)) =>
          dispatch({ type: "SET", payload }),
        []
      );
      const reset = useCallback(
        (payload?: T) => dispatch({ type: "RESET", payload }),
        []
      );
      const merge = useCallback(
        (payload: Partial<t>) => dispatch({ type: "MERGE", payload }),
        []
      );
    
      const memoizedState = useMemo(() => state, [state]);
    
      return [memoizedState, { set, reset, merge }] as const;
    }
    
    export default useCustomReducer;
    </t></t></t></t></t></t></t></t></t></primitive>
    • Réinitialiser à l'état initial :
    import useCustomReducer from "./use-custom-reducer";
    import { faker } from "@faker-js/faker";
    import { Button } from "@/components/ui/button";
    
    export default function Use() {
      const [formValues, { set, reset, merge }] = useCustomReducer({
        name: faker.person.firstName(),
        age: faker.number.int({ min: 18, max: 99 }),
        address: {
          street: faker.location.streetAddress(),
          city: faker.location.city(),
          state: faker.location.state(),
          zip: faker.location.zipCode(),
        },
        hobbies: [faker.person.bio(), faker.person.bio(), faker.person.bio()],
      });
    
      const [bool, { set: setBool }] = useCustomReducer<boolean>(
        faker.datatype.boolean()
      );
      const [num, { set: setNum }] = useCustomReducer(faker.number.int());
      const [str, { set: setStr }] = useCustomReducer<string>(faker.lorem.word());
      const [date, { set: setDate }] = useCustomReducer(faker.date.recent());
      const [nil, { set: setNil }] = useCustomReducer(null);
      const [undef, { set: setUndef }] = useCustomReducer(undefined);
      const [arr, { set: setArr }] = useCustomReducer([
        faker.number.int(),
        faker.number.int(),
        faker.number.int(),
      ]);
      const [nestedArr, { set: setNestedArr }] = useCustomReducer([
        faker.number.int(),
        faker.lorem.word(),
        { three: faker.number.float() },
      ]);
    
      const [obj, { set: setObj }] = useCustomReducer({
        a: faker.number.int(),
        b: faker.number.int(),
        c: faker.number.int(),
      });
      const [nestedObj, { set: setNestedObj }] = useCustomReducer({
        a: faker.number.int(),
        b: faker.lorem.word(),
        c: { three: faker.number.float() },
      });
    
      return (
        <div classname="p-4 space-y-6">
          <h1 id="Use">Use</h1>
          <div classname="space-x-2 space-y-2">
            <h2 id="Form-Values">Form Values</h2>
            <p classname="text-gray-500">{JSON.stringify(formValues)}</p>
            <button onclick="{()"> set({ name: faker.person.firstName() })}>
              Set Name
            </button>
            <button onclick="{()"> set((prevState) => ({ age: prevState.age - 1 }))}
            >
              Decrement Age
            </button>
            <button onclick="{()"> set((prevState) => ({ age: prevState.age + 1 }))}
            >
              Increment Age
            </button>
            <button onclick="{()">
                set((prevState) => ({
                  address: {
                    ...prevState.address,
                    street: faker.location.streetAddress(),
                  },
                }))
              }
            >
              Set Street
            </button>
            <button onclick="{()"> reset()}>Reset</button>
            <button onclick="{()"> merge({ age: faker.number.int({ min: 18, max: 99 }) })}
            >
              Merge
            </button>
          </div>
          <hr classname="border-t border-gray-300">
          <div classname="space-x-2 space-y-2">
            <h2 id="Boolean-Value">Boolean Value</h2>
            <p classname="text-gray-500">{bool.toString()}</p>
            <button onclick="{()"> setBool(faker.datatype.boolean())}>
              Set Bool
            </button>
          </div>
          <hr classname="border-t border-gray-300">
          <div classname="space-x-2 space-y-2">
            <h2 id="Number-Value">Number Value</h2>
            <p classname="text-gray-500">{num.toString()}</p>
            <button onclick="{()"> setNum(faker.number.int())}>Set Num</button>
          </div>
          <hr classname="border-t border-gray-300">
          <div classname="space-x-2 space-y-2">
            <h2 id="String-Value">String Value</h2>
            <p classname="text-gray-500">{str}</p>
            <button onclick="{()"> setStr(faker.lorem.word())}>Set Str</button>
          </div>
          <hr classname="border-t border-gray-300">
          <div classname="space-x-2 space-y-2">
            <h2 id="Date-Value">Date Value</h2>
            <p classname="text-gray-500">{JSON.stringify(date)}</p>
            <button onclick="{()"> setDate(faker.date.recent())}>Set Date</button>
            <button onclick="{()"> setDate(new Date("2022-01-01"))}>
              Set Date to 2022
            </button>
          </div>
          <hr classname="border-t border-gray-300">
          <div classname="space-x-2 space-y-2">
            <h2 id="Nil-and-Undefined">Nil and Undefined</h2>
            <p classname="text-gray-500">{String(nil)}</p>
            <button onclick="{()"> setNil(null)}>Set Nil</button>
            <p classname="text-gray-500">{String(undef)}</p>
            <button onclick="{()"> setUndef(undefined)}>Set Undef</button>
          </div>
          <hr classname="border-t border-gray-300">
          <div classname="space-x-2 space-y-2">
            <h2 id="Array-Value">Array Value</h2>
            <p classname="text-gray-500">{arr.toString()}</p>
            <button onclick="{()">
                setArr([faker.number.int(), faker.number.int(), faker.number.int()])
              }
            >
              Set Arr
            </button>
          </div>
          <hr classname="border-t border-gray-300">
          <div classname="space-x-2 space-y-2">
            <h2 id="Nested-Array">Nested Array</h2>
            <p classname="text-gray-500">{JSON.stringify(nestedArr)}</p>
            <button onclick="{()">
                setNestedArr([
                  faker.number.int(),
                  faker.lorem.word(),
                  { three: faker.number.float() },
                ])
              }
            >
              Set Nested Arr
            </button>
          </div>
          <hr classname="border-t border-gray-300">
          <div classname="space-x-2 space-y-2">
            <h2 id="Object-Value">Object Value</h2>
            <p classname="text-gray-500">{JSON.stringify(obj)}</p>
            <button onclick="{()">
                setObj({
                  a: faker.number.int(),
                  b: faker.number.int(),
                  c: faker.number.int(),
                })
              }
            >
              Set Obj
            </button>
          </div>
          <hr classname="border-t border-gray-300">
          <div classname="space-x-2 space-y-2">
            <h2 id="Nested-Object">Nested Object</h2>
            <p classname="text-gray-500">{JSON.stringify(nestedObj)}</p>
            <button onclick="{()">
                setNestedObj({
                  a: faker.number.int(),
                  b: faker.lorem.word(),
                  c: { three: faker.number.float() },
                })
              }
            >
              Set Nested Obj
            </button>
          </div>
        </div>
      );
    }
    </string></boolean>
  • Booléen :

function useCustomReducer<t extends state>(
  initialState: T
): [
  T,
  {
    set: (payload: Partial<t> | ((prevState: T) => Partial<t>)) => void;
    reset: (payload?: T) => void;
    merge: (payload: Partial<t>) => void;
  }
];
</t></t></t></t>
  • Utilisation :

    • Basculez le booléen :
    const [state, { set }] = useCustomReducer({ count: 0 });
    
    set((prevState) => ({ count: prevState.count + 1 }));
    
    • Réinitialiser à l'état initial :
    reset(); // Resets to initial state.
    
    reset({ name: "John", age: 25 }); // Resets to a new state.
    
    • Définissez une nouvelle valeur :
    merge({ city: "New York" }); // Adds or updates the 'city' field.
    
  • Date :

const initialState = 0;

const [count, { set, reset }] = useCustomReducer(initialState);
  • Utilisation :

    • Mettre à jour la date :
    set((prevState) => prevState + 1);
    
    • Réinitialiser à l'état initial :
    reset();
    
    • Définissez une nouvelle valeur :
      set(10);
    
  • États nuls et non définis :

const initialState = "Hello, World!";

const [message, { set, reset }] = useCustomReducer(initialState);
  • Utilisation :

    • Définissez une nouvelle valeur :
    set("Hello, React!");
    
    • Réinitialiser à l'état initial :
    reset();
    
    • Définissez une nouvelle valeur :
    const initialState = false;
    
    const [isToggled, { set, reset }] = useCustomReducer(initialState);
    

Gestion des données de formulaire

  • État initial :
set((prevState) => !prevState);
  • Utilisation :

    • Définissez un nouveau nom :
    reset();
    
    • Mettre à jour l'adresse partiellement :
      set(true);
    
    • Définissez un nouveau nom :
    const initialState = new Date();
    
    const [date, { set, reset }] = useCustomReducer(initialState);
    
    • Mettre à jour la ville :
    set(new Date("2022-01-01"));
    
    • Fusionner les champs supplémentaires :
    reset();
    
    • Réinitialiser à l'état initial :
    set(new Date("2023-01-01"));
    

Gestion des tableaux

  • État initial :
const initialState: string | null = null;
const initialState: string | undefined = undefined;

const [value, { set, reset }] = useCustomReducer(initialState); // Implicitly infer the type.
const [value, { set, reset }] = useCustomReducer<string undefined>(
  initialState
); // Explicitly define the type.
</string>
  • Utilisation :

    • Ajouter un nouvel élément :
    set("New Value");
    
    • Supprimer un élément :
    reset();
    
    • Réinitialiser à l'état initial :
    set("New Value");
    
    • Définissez une nouvelle valeur :
    const initialState = {
      name: "John Doe",
      age: 30,
      address: {
        street: "123 Main St",
        city: "Sample City",
        state: "CA",
      },
    };
    
    const [formData, { set, reset, merge }] = useCustomReducer(initialState);
    
    • Fusionner des éléments supplémentaires :
    set({ name: "Jane Doe" });
    
  • État initial des tableaux imbriqués :

set((prevState) => ({
  address: {
    ...prevState.address,
    city: "New City",
  },
}));
  • Utilisation :

    • Ajouter un nouvel utilisateur :
    set({ name: "Jane Doe" });
    
    • Supprimer un utilisateur :
    merge({ address: { city: "New York" } });
    
    • Réinitialiser à l'état initial :
    merge({ phone: "123-456-7890" });
    
    • Définissez une nouvelle valeur :
    reset();
    
    • Fusionner des utilisateurs supplémentaires :
    const initialState = [1, 2, 3, 4, 5];
    
    const [numbers, { set, reset, merge }] = useCustomReducer(initialState);
    

Gestion de l'état imbriqué

  • État initial :
set((prevState) => [...prevState, 6]);
  • Utilisation :

    • Mettre à jour l'âge de l'utilisateur :
    set((prevState) => prevState.filter((item) => item !== 3));
    
    • Mettre à jour la ville :
    reset();
    
    • Réinitialiser à l'état initial :
      set([10, 20, 30]);
    
    • Définissez une nouvelle valeur :
      merge([6, 7, 8]);
    

Pourquoi utiliser useCustomReducer ?

  • Gestion d'état flexible :

    • Prend en charge diverses structures étatiques, ce qui le rend adapté à différents cas d'utilisation.
    • Gère facilement les états primitifs, imbriqués et basés sur des tableaux.
    • Fournit des méthodes pour mettre à jour, réinitialiser et fusionner les valeurs d'état.
  • API simple :

    • Fournit des méthodes intuitives pour mettre à jour, réinitialiser et fusionner des valeurs.
    • Prend en charge les mises à jour directes et les fonctions de rappel pour les changements d'état dynamiques.
    • Offre un moyen propre et déclaratif de gérer l'état dans les composants React.
  • Code du nettoyeur :

    • Réduit le code passe-partout en gérant efficacement les structures étatiques complexes.
    • Évitez les déclarations useState répétitives et gérez directement les états complexes.
    • Gérez tous les types d'état (primitif, objet, tableau, etc.) avec un seul hook.
  • Type-Safe :

    • Entièrement tapé à l'aide de TypeScript pour un développement fiable et une prévention des erreurs.
  • Mises à jour dynamiques :

    • Utilisez la méthode set avec des fonctions pour calculer dynamiquement l'état suivant.

Conclusion

Le hook useCustomReducer est un outil puissant pour gérer des structures d'état complexes dans les applications React. En combinant la flexibilité de useReducer avec une API simple pour mettre à jour l'état, ce hook simplifie la gestion de l'état et réduit le code passe-partout. Que vous ayez affaire à des valeurs primitives, des objets imbriqués ou des tableaux, le hook useCustomReducer fournit un moyen propre et déclaratif de gérer les changements d'état. Essayez-le dans votre prochain projet et découvrez facilement les avantages d'une gestion d'état polyvalente.

Ressources supplémentaires

  • Documentation React
  • Documentation TypeScript
  • Documentation Faker.js

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Applications JavaScript: de front-end à back-endApplications JavaScript: de front-end à back-endMay 04, 2025 am 12:12 AM

JavaScript peut être utilisé pour le développement frontal et back-end. L'endouage frontal améliore l'expérience utilisateur via les opérations DOM, et le back-end gère les tâches du serveur via Node.js. 1. Exemple frontal: modifiez le contenu du texte de la page Web. 2. Exemple backend: Créez un serveur Node.js.

Python vs JavaScript: Quelle langue devez-vous apprendre?Python vs JavaScript: Quelle langue devez-vous apprendre?May 03, 2025 am 12:10 AM

Le choix de Python ou JavaScript doit être basé sur le développement de carrière, la courbe d'apprentissage et l'écosystème: 1) le développement de carrière: Python convient à la science des données et au développement de back-end, tandis que JavaScript convient au développement frontal et complet. 2) Courbe d'apprentissage: la syntaxe Python est concise et adaptée aux débutants; La syntaxe JavaScript est flexible. 3) Ecosystème: Python possède de riches bibliothèques informatiques scientifiques, et JavaScript a un puissant cadre frontal.

Frameworks javascript: alimenter le développement Web moderneFrameworks javascript: alimenter le développement Web moderneMay 02, 2025 am 12:04 AM

La puissance du cadre JavaScript réside dans la simplification du développement, l'amélioration de l'expérience utilisateur et les performances des applications. Lorsque vous choisissez un cadre, considérez: 1. Taille et complexité du projet, 2. Expérience d'équipe, 3. Écosystème et soutien communautaire.

La relation entre JavaScript, C et BrowsersLa relation entre JavaScript, C et BrowsersMay 01, 2025 am 12:06 AM

INTRODUCTION Je sais que vous pouvez le trouver étrange, que doit faire exactement JavaScript, C et Browser? Ils semblent sans rapport, mais en fait, ils jouent un rôle très important dans le développement Web moderne. Aujourd'hui, nous discuterons du lien étroit entre ces trois. Grâce à cet article, vous apprendrez comment JavaScript fonctionne dans le navigateur, le rôle de C dans le moteur du navigateur et comment ils fonctionnent ensemble pour stimuler le rendu et l'interaction des pages Web. Nous connaissons tous la relation entre JavaScript et Browser. JavaScript est la langue principale du développement frontal. Il fonctionne directement dans le navigateur, rendant les pages Web vives et intéressantes. Vous êtes-vous déjà demandé pourquoi javascr

Node.js diffuse avec dactylographieNode.js diffuse avec dactylographieApr 30, 2025 am 08:22 AM

Node.js excelle dans des E / S efficaces, en grande partie grâce aux flux. Streams traite les données progressivement, en évitant la surcharge de mémoire - idéal pour les fichiers volumineux, les tâches réseau et les applications en temps réel. Combiner les flux avec la sécurité de type dactylographié crée un powe

Python vs JavaScript: considérations de performance et d'efficacitéPython vs JavaScript: considérations de performance et d'efficacitéApr 30, 2025 am 12:08 AM

Les différences de performance et d'efficacité entre Python et JavaScript se reflètent principalement dans: 1) comme un langage interprété, Python fonctionne lentement mais a une efficacité de développement élevée et convient au développement rapide des prototypes; 2) JavaScript est limité au thread unique dans le navigateur, mais les E / S multi-threading et asynchrones peuvent être utilisées pour améliorer les performances dans Node.js, et les deux ont des avantages dans les projets réels.

Les origines de JavaScript: explorer son langage d'implémentationLes origines de JavaScript: explorer son langage d'implémentationApr 29, 2025 am 12:51 AM

JavaScript est originaire de 1995 et a été créé par Brandon Ike, et a réalisé que la langue en langue C. 1.C offre des capacités de programmation élevées et au niveau du système pour JavaScript. 2. La gestion de la mémoire de JavaScript et l'optimisation des performances reposent sur le langage C. 3. La fonctionnalité multiplateforme du langage C aide JavaScript à s'exécuter efficacement sur différents systèmes d'exploitation.

Dans les coulisses: quel langage alimente JavaScript?Dans les coulisses: quel langage alimente JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript s'exécute dans les navigateurs et les environnements Node.js et s'appuie sur le moteur JavaScript pour analyser et exécuter du code. 1) Générer une arborescence de syntaxe abstraite (AST) au stade d'analyse; 2) Convertir AST en bytecode ou code machine à l'étape de compilation; 3) Exécutez le code compilé à l'étape d'exécution.

See all articles

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

SublimeText3 Linux nouvelle version

SublimeText3 Linux nouvelle version

Dernière version de SublimeText3 Linux

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Puissant environnement de développement intégré PHP

DVWA

DVWA

Damn Vulnerable Web App (DVWA) est une application Web PHP/MySQL très vulnérable. Ses principaux objectifs sont d'aider les professionnels de la sécurité à tester leurs compétences et leurs outils dans un environnement juridique, d'aider les développeurs Web à mieux comprendre le processus de sécurisation des applications Web et d'aider les enseignants/étudiants à enseigner/apprendre dans un environnement de classe. Application Web sécurité. L'objectif de DVWA est de mettre en pratique certaines des vulnérabilités Web les plus courantes via une interface simple et directe, avec différents degrés de difficulté. Veuillez noter que ce logiciel

Version crackée d'EditPlus en chinois

Version crackée d'EditPlus en chinois

Petite taille, coloration syntaxique, ne prend pas en charge la fonction d'invite de code

Adaptateur de serveur SAP NetWeaver pour Eclipse

Adaptateur de serveur SAP NetWeaver pour Eclipse

Intégrez Eclipse au serveur d'applications SAP NetWeaver.