Maison > interface Web > js tutoriel > useCustomReducer Hook : un outil de gestion d'état polyvalent

useCustomReducer Hook : un outil de gestion d'état polyvalent

Mary-Kate Olsen
Libérer: 2024-12-14 17:44:11
original
453 Les gens l'ont consulté

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;
Copier après la connexion
Copier après la connexion

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 className="text-2xl font-bold">Use</h1>
      <div className="space-x-2 space-y-2">
        <h2 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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>
  );
}
Copier après la connexion
Copier après la connexion

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;
  }
];
Copier après la connexion
Copier après la connexion

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 }));
Copier après la connexion
Copier après la connexion
  • 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.
Copier après la connexion
Copier après la connexion
  • 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.
Copier après la connexion
Copier après la connexion

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);
Copier après la connexion
Copier après la connexion
  • Utilisation :

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

const initialState = "Hello, World!";

const [message, { set, reset }] = useCustomReducer(initialState);
Copier après la connexion
Copier après la connexion
  • 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;
    
    Copier après la connexion
    Copier après la connexion
    • 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 className="text-2xl font-bold">Use</h1>
          <div className="space-x-2 space-y-2">
            <h2 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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 className="text-lg font-semibold">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>
      );
    }
    
    Copier après la connexion
    Copier après la connexion
  • 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;
  }
];
Copier après la connexion
Copier après la connexion
  • Utilisation :

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

const initialState = 0;

const [count, { set, reset }] = useCustomReducer(initialState);
Copier après la connexion
Copier après la connexion
  • Utilisation :

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

const initialState = "Hello, World!";

const [message, { set, reset }] = useCustomReducer(initialState);
Copier après la connexion
Copier après la connexion
  • Utilisation :

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

Gestion des données de formulaire

  • État initial :
set((prevState) => !prevState);
Copier après la connexion
  • Utilisation :

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

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.
Copier après la connexion
  • Utilisation :

    • Ajouter un nouvel élément :
    set("New Value");
    
    Copier après la connexion
    Copier après la connexion
    • Supprimer un élément :
    reset();
    
    Copier après la connexion
    Copier après la connexion
    Copier après la connexion
    Copier après la connexion
    Copier après la connexion
    Copier après la connexion
    Copier après la connexion
    Copier après la connexion
    • Réinitialiser à l'état initial :
    set("New Value");
    
    Copier après la connexion
    Copier après la connexion
    • 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);
    
    Copier après la connexion
    • Fusionner des éléments supplémentaires :
    set({ name: "Jane Doe" });
    
    Copier après la connexion
    Copier après la connexion
  • État initial des tableaux imbriqués :

set((prevState) => ({
  address: {
    ...prevState.address,
    city: "New City",
  },
}));
Copier après la connexion
  • Utilisation :

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

Gestion de l'état imbriqué

  • État initial :
set((prevState) => [...prevState, 6]);
Copier après la connexion
  • Utilisation :

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

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!

source:dev.to
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal