Heim > Web-Frontend > js-Tutorial > useCustomReducer Hook: Ein vielseitiges Statusverwaltungstool

useCustomReducer Hook: Ein vielseitiges Statusverwaltungstool

Mary-Kate Olsen
Freigeben: 2024-12-14 17:44:11
Original
453 Leute haben es durchsucht

useCustomReducer Hook: A Versatile State Management Tool

Einführung

Die Zustandsverwaltung in React kann schwierig sein, insbesondere wenn es um komplexe oder verschachtelte Zustandsstrukturen geht. Um dies zu vereinfachen, kombiniert der useCustomReducer-Hook die Leistungsfähigkeit von useReducer mit einer flexiblen API zum Aktualisieren des Status auf saubere, deklarative Weise. Dieser Hook unterstützt primitive, verschachtelte und Array-Zustände und eignet sich daher für eine Vielzahl von Anwendungsfällen.

In diesem Artikel untersuchen wir den useCustomReducer-Hook und seine Kernmethoden zum Verwalten des Status in React-Anwendungen. Wir behandeln die Definition des Hooks, seine Methodensignaturen und detaillierte Anwendungsbeispiele für verschiedene Arten von Zustandsstrukturen. Am Ende verfügen Sie über ein solides Verständnis dafür, wie Sie den useCustomReducer-Hook verwenden, um komplexe Zustände in Ihren React-Komponenten zu verarbeiten.

 Inhaltsverzeichnis

  • Einführung
  • Inhaltsverzeichnis
  • Hooks-Übersicht
  • Beispiel für eine Reaktionskomponente
  • Funktionen
  • Definition
    • Methodendefinitionen
  • Detaillierte Anwendungsbeispiele
    • Primitive verwalten
    • Formulardaten verwalten
    • Arrays verwalten
    • Verschachtelungsstatus verwalten
  • Warum useCustomReducer verwenden?
  • Fazit
  • Zusätzliche Ressourcen

Hooks-Übersicht

Der useCustomReducer-Hook ist ein benutzerdefinierter React-Hook, der eine einfache und flexible Möglichkeit bietet, komplexe Zustandsstrukturen zu verwalten. Es kombiniert die Vorteile von useReducer mit einer sauberen API zum Aktualisieren von Statuswerten. Dieser Hook ist für die Verarbeitung verschiedener Zustandstypen konzipiert, darunter Grundwerte, Objekte, Arrays und verschachtelte Datenstrukturen.

Hier ist eine Übersicht über den useCustomReducer-Hook:

  • Kernmethoden:

    • set: Zustandswerte direkt oder über eine Callback-Funktion aktualisieren.
    • Zurücksetzen: Zustand auf seinen Anfangswert zurücksetzen.
    • merge: Teilaktualisierungen in den bestehenden Zustand einbinden.
  • Zustandsstrukturen: - Unterstützt primitive Werte (z. B. Zahlen, Zeichenfolgen, Boolesche Werte). - Verarbeitet objektbasierte Zustandsstrukturen (z. B. Formulardaten, Benutzerprofile). - Verwaltet Array-basierte Zustandsstrukturen (z. B. Listen, Sammlungen).

  • Typsicher: - Vollständig typisiert mit TypeScript für zuverlässige Entwicklung und Fehlervermeidung.

  • Einfache API: – Bietet intuitive Methoden zum Aktualisieren, Zurücksetzen und Zusammenführen von Statuswerten. - Unterstützt direkte Aktualisierungen und Rückruffunktionen für dynamische Statusänderungen.

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;
Nach dem Login kopieren
Nach dem Login kopieren

Der useCustomReducer-Hook wird mithilfe des useReducer-Hooks von React implementiert. Es definiert eine benutzerdefinierte Reduzierfunktion, die verschiedene Arten von Aktionen zum Aktualisieren, Zurücksetzen oder Zusammenführen von Statuswerten verarbeitet. Der Hook bietet drei Kernmethoden zum Festlegen, Zurücksetzen und Zusammenführen, um mit dem Status zu interagieren. Die Set-Methode kann entweder ein Objekt mit neuen Statuswerten oder eine Rückruffunktion akzeptieren, um den nächsten Status zu berechnen. Die Reset-Methode setzt den Zustand auf seinen Anfangswert zurück, während die Merge-Methode Teilaktualisierungen in den bestehenden Zustand einfügt.

Beispiel für eine Reaktionskomponente

Hier ist ein Beispiel für die Verwendung des useCustomReducer-Hooks in einer React-Komponente, um einen einfachen Zählerstatus zu verwalten:

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>
  );
}
Nach dem Login kopieren
Nach dem Login kopieren

Merkmale

  • Unterstützt verschiedene Zustandsstrukturen: Behandelt Grundelemente, Objekte, Arrays und verschachtelte Datenstrukturen.

  • Einfache API:

    • set: Zustandswerte direkt oder über einen Rückruf aktualisieren.
    • Zurücksetzen: Zustand auf seinen Anfangswert zurücksetzen.
    • merge: Teilaktualisierungen in den bestehenden Zustand einbinden.
  • Typsicher: Vollständig typisiert mit TypeScript für zuverlässige Entwicklung.

Definition

Der useCustomReducer-Hook ist ein benutzerdefinierter React-Hook zur Verwaltung komplexer Zustände. Es bietet drei Kernmethoden zum Festlegen, Zurücksetzen und Zusammenführen, um primitive, verschachtelte und arraybasierte Zustandsstrukturen zu verarbeiten. Hier ist eine Aufschlüsselung des Hooks und seiner Methoden:

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;
  }
];
Nach dem Login kopieren
Nach dem Login kopieren

Methodendefinitionen

  • Satz
    • Aktualisiert den Status durch Ersetzen oder teilweises Aktualisieren seiner Eigenschaften.
    • Akzeptiert entweder:
    • Ein Objekt mit neuen Zustandswerten.
    • Eine Rückruffunktion (prevState) => Teilweise zur Berechnung des nächsten Zustands.

Beispiel

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

set((prevState) => ({ count: prevState.count + 1 }));
Nach dem Login kopieren
Nach dem Login kopieren
  • zurücksetzen
    • Setzt den Zustand auf den Anfangszustand oder einen angegebenen Wert zurück.
    • Akzeptiert eine optionale Nutzlast, um den Anfangszustand zu ersetzen.

Beispiel

reset(); // Resets to initial state.

reset({ name: "John", age: 25 }); // Resets to a new state.
Nach dem Login kopieren
Nach dem Login kopieren
  • verschmelzen
    • Führt Teilaktualisierungen in den bestehenden Zustand ein.
    • Akzeptiert ein Objekt mit teilweisen Statusaktualisierungen.
    • Funktioniert nur für Objekte und verschachtelte Zustandsstrukturen.

Beispiel

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

Detaillierte Anwendungsbeispiele

Der useCustomReducer-Hook ist vielseitig und kann zur Verwaltung verschiedener Arten von Zustandsstrukturen verwendet werden. Hier sind einige Beispiele, um die Verwendung mit verschiedenen Zustandstypen zu veranschaulichen:

 Primitive verwalten

  • Nummer:
const initialState = 0;

const [count, { set, reset }] = useCustomReducer(initialState);
Nach dem Login kopieren
Nach dem Login kopieren
  • Verwendung:

    • Erhöhen Sie die Anzahl:
    set((prevState) => prevState + 1);
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Zurücksetzen auf den Ausgangszustand:
    reset();
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Neuen Wert festlegen:
      set(10);
    
    Nach dem Login kopieren
    Nach dem Login kopieren
  • Zeichenfolge:

const initialState = "Hello, World!";

const [message, { set, reset }] = useCustomReducer(initialState);
Nach dem Login kopieren
Nach dem Login kopieren
  • Verwendung:

    • Aktualisieren Sie die Zeichenfolge:
    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;
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Zurücksetzen auf den Ausgangszustand:
    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>
      );
    }
    
    Nach dem Login kopieren
    Nach dem Login kopieren
  • Boolescher Wert:

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;
  }
];
Nach dem Login kopieren
Nach dem Login kopieren
  • Verwendung:

    • Booleschen Wert umschalten:
    const [state, { set }] = useCustomReducer({ count: 0 });
    
    set((prevState) => ({ count: prevState.count + 1 }));
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Zurücksetzen auf den Ausgangszustand:
    reset(); // Resets to initial state.
    
    reset({ name: "John", age: 25 }); // Resets to a new state.
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Neuen Wert festlegen:
    merge({ city: "New York" }); // Adds or updates the 'city' field.
    
    Nach dem Login kopieren
    Nach dem Login kopieren
  • Datum:

const initialState = 0;

const [count, { set, reset }] = useCustomReducer(initialState);
Nach dem Login kopieren
Nach dem Login kopieren
  • Verwendung:

    • Datum aktualisieren:
    set((prevState) => prevState + 1);
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Zurücksetzen auf den Ausgangszustand:
    reset();
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Neuen Wert festlegen:
      set(10);
    
    Nach dem Login kopieren
    Nach dem Login kopieren
  • Null- und undefinierte Zustände:

const initialState = "Hello, World!";

const [message, { set, reset }] = useCustomReducer(initialState);
Nach dem Login kopieren
Nach dem Login kopieren
  • Verwendung:

    • Neuen Wert festlegen:
    set("Hello, React!");
    
    Nach dem Login kopieren
    • Zurücksetzen auf den Ausgangszustand:
    reset();
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Neuen Wert festlegen:
    const initialState = false;
    
    const [isToggled, { set, reset }] = useCustomReducer(initialState);
    
    Nach dem Login kopieren

Formulardaten verwalten

  • Ausgangszustand:
set((prevState) => !prevState);
Nach dem Login kopieren
  • Verwendung:

    • Neuen Namen festlegen:
    reset();
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Adresse teilweise aktualisieren:
      set(true);
    
    Nach dem Login kopieren
    • Neuen Namen festlegen:
    const initialState = new Date();
    
    const [date, { set, reset }] = useCustomReducer(initialState);
    
    Nach dem Login kopieren
    • Aktualisieren Sie die Stadt:
    set(new Date("2022-01-01"));
    
    Nach dem Login kopieren
    • Zusätzliche Felder zusammenführen:
    reset();
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Zurücksetzen auf den Ausgangszustand:
    set(new Date("2023-01-01"));
    
    Nach dem Login kopieren

Arrays verwalten

  • Ausgangszustand:
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.
Nach dem Login kopieren
  • Verwendung:

    • Neues Element hinzufügen:
    set("New Value");
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Ein Element entfernen:
    reset();
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Zurücksetzen auf den Ausgangszustand:
    set("New Value");
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Neuen Wert festlegen:
    const initialState = {
      name: "John Doe",
      age: 30,
      address: {
        street: "123 Main St",
        city: "Sample City",
        state: "CA",
      },
    };
    
    const [formData, { set, reset, merge }] = useCustomReducer(initialState);
    
    Nach dem Login kopieren
    • Zusätzliche Elemente zusammenführen:
    set({ name: "Jane Doe" });
    
    Nach dem Login kopieren
    Nach dem Login kopieren
  • Anfangszustand für verschachtelte Arrays:

set((prevState) => ({
  address: {
    ...prevState.address,
    city: "New City",
  },
}));
Nach dem Login kopieren
  • Verwendung:

    • Neuen Benutzer hinzufügen:
    set({ name: "Jane Doe" });
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Einen Benutzer entfernen:
    merge({ address: { city: "New York" } });
    
    Nach dem Login kopieren
    • Zurücksetzen auf den Ausgangszustand:
    merge({ phone: "123-456-7890" });
    
    Nach dem Login kopieren
    • Neuen Wert festlegen:
    reset();
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Zusätzliche Benutzer zusammenführen:
    const initialState = [1, 2, 3, 4, 5];
    
    const [numbers, { set, reset, merge }] = useCustomReducer(initialState);
    
    Nach dem Login kopieren

Verwalten des verschachtelten Zustands

  • Ausgangszustand:
set((prevState) => [...prevState, 6]);
Nach dem Login kopieren
  • Verwendung:

    • Alter des Benutzers aktualisieren:
    set((prevState) => prevState.filter((item) => item !== 3));
    
    Nach dem Login kopieren
    • Aktualisieren Sie die Stadt:
    reset();
    
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    Nach dem Login kopieren
    • Zurücksetzen auf den Ausgangszustand:
      set([10, 20, 30]);
    
    Nach dem Login kopieren
    • Neuen Wert festlegen:
      merge([6, 7, 8]);
    
    Nach dem Login kopieren

Warum useCustomReducer verwenden?

  • Flexibles Zustandsmanagement:

    • Unterstützt verschiedene Zustandsstrukturen und eignet sich daher für verschiedene Anwendungsfälle.
    • Verarbeitet problemlos primitive, verschachtelte und Array-basierte Zustände.
    • Stellt Methoden zum Aktualisieren, Zurücksetzen und Zusammenführen von Statuswerten bereit.
  • Einfache API:

    • Bietet intuitive Methoden zum Aktualisieren, Zurücksetzen und Zusammenführen von Werten.
    • Unterstützt direkte Aktualisierungen und Rückruffunktionen für dynamische Statusänderungen.
    • Bietet eine saubere und deklarative Möglichkeit, den Status in React-Komponenten zu verwalten.
  • Cleaner-Code:

    • Reduziert den Boilerplate-Code durch effiziente Handhabung komplexer Zustandsstrukturen.
    • Vermeiden Sie sich wiederholende useState-Deklarationen und verarbeiten Sie komplexe Zustände direkt.
    • Verwalten Sie alle Zustandstypen (primitiv, Objekt, Array usw.) mit einem Hook.
  • Typsicher:

    • Vollständig typisiert mit TypeScript für zuverlässige Entwicklung und Fehlervermeidung.
  • Dynamische Updates:

    • Verwenden Sie die Set-Methode mit Funktionen, um den nächsten Zustand dynamisch zu berechnen.

Abschluss

Der useCustomReducer-Hook ist ein leistungsstarkes Tool zum Verwalten komplexer Zustandsstrukturen in React-Anwendungen. Durch die Kombination der Flexibilität von useReducer mit einer einfachen API zum Aktualisieren des Status vereinfacht dieser Hook die Statusverwaltung und reduziert den Boilerplate-Code. Unabhängig davon, ob Sie mit primitiven Werten, verschachtelten Objekten oder Arrays arbeiten, bietet der useCustomReducer-Hook eine saubere und deklarative Möglichkeit, Zustandsänderungen zu verarbeiten. Probieren Sie es bei Ihrem nächsten Projekt aus und erleben Sie ganz einfach die Vorteile einer vielseitigen Zustandsverwaltung.

Zusätzliche Ressourcen

  • React Documentation
  • TypeScript-Dokumentation
  • Faker.js-Dokumentation

Das obige ist der detaillierte Inhalt vonuseCustomReducer Hook: Ein vielseitiges Statusverwaltungstool. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage