useCustomReducer Hook : un outil de gestion d'état polyvalent
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;
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> ); }
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; } ];
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);
Copier après la connexionCopier après la connexion- Réinitialiser à l'état initial :
reset();
Copier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexion- Définissez une nouvelle valeur :
set(10);
Copier après la connexionCopier après la connexion 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;
Copier après la connexionCopier 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 connexionCopier 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; } ];
-
Utilisation :
- Basculez le booléen :
const [state, { set }] = useCustomReducer({ count: 0 }); set((prevState) => ({ count: prevState.count + 1 }));
Copier après la connexionCopier 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 connexionCopier après la connexion- Définissez une nouvelle valeur :
merge({ city: "New York" }); // Adds or updates the 'city' field.
Copier après la connexionCopier après la connexion Date :
const initialState = 0; const [count, { set, reset }] = useCustomReducer(initialState);
-
Utilisation :
- Mettre à jour la date :
set((prevState) => prevState + 1);
Copier après la connexionCopier après la connexion- Réinitialiser à l'état initial :
reset();
Copier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexion- Définissez une nouvelle valeur :
set(10);
Copier après la connexionCopier après la connexion É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!");
Copier après la connexion- Réinitialiser à l'état initial :
reset();
Copier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier 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);
-
Utilisation :
- Définissez un nouveau nom :
reset();
Copier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier 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 connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier 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.
-
Utilisation :
- Ajouter un nouvel élément :
set("New Value");
Copier après la connexionCopier après la connexion- Supprimer un élément :
reset();
Copier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexion- Réinitialiser à l'état initial :
set("New Value");
Copier après la connexionCopier 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 connexionCopier après la connexion État initial des tableaux imbriqués :
set((prevState) => ({ address: { ...prevState.address, city: "New City", }, }));
-
Utilisation :
- Ajouter un nouvel utilisateur :
set({ name: "Jane Doe" });
Copier après la connexionCopier 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 connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier 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]);
-
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 connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier après la connexionCopier 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!

Outils d'IA chauds

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

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

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

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 !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Des questions et des solutions fréquemment posées pour l'impression de billets thermiques frontaux pour le développement frontal, l'impression de billets est une exigence commune. Cependant, de nombreux développeurs mettent en œuvre ...

JavaScript est la pierre angulaire du développement Web moderne, et ses principales fonctions incluent la programmation axée sur les événements, la génération de contenu dynamique et la programmation asynchrone. 1) La programmation axée sur les événements permet aux pages Web de changer dynamiquement en fonction des opérations utilisateur. 2) La génération de contenu dynamique permet d'ajuster le contenu de la page en fonction des conditions. 3) La programmation asynchrone garantit que l'interface utilisateur n'est pas bloquée. JavaScript est largement utilisé dans l'interaction Web, les applications à une page et le développement côté serveur, améliorant considérablement la flexibilité de l'expérience utilisateur et du développement multiplateforme.

Il n'y a pas de salaire absolu pour les développeurs Python et JavaScript, selon les compétences et les besoins de l'industrie. 1. Python peut être davantage payé en science des données et en apprentissage automatique. 2. JavaScript a une grande demande dans le développement frontal et complet, et son salaire est également considérable. 3. Les facteurs d'influence comprennent l'expérience, la localisation géographique, la taille de l'entreprise et les compétences spécifiques.

La discussion sur la réalisation des effets de défilement de parallaxe et d'animation des éléments dans cet article explorera comment réaliser le site officiel de Shiseido (https://www.shiseido.co.jp/sb/wonderland/) ...

Les dernières tendances de JavaScript incluent la montée en puissance de TypeScript, la popularité des frameworks et bibliothèques modernes et l'application de WebAssembly. Les prospects futurs couvrent des systèmes de type plus puissants, le développement du JavaScript côté serveur, l'expansion de l'intelligence artificielle et de l'apprentissage automatique, et le potentiel de l'informatique IoT et Edge.

Apprendre JavaScript n'est pas difficile, mais c'est difficile. 1) Comprendre les concepts de base tels que les variables, les types de données, les fonctions, etc. 2) Master la programmation asynchrone et les implémenter via des boucles d'événements. 3) Utilisez les opérations DOM et promettez de gérer les demandes asynchrones. 4) Évitez les erreurs courantes et utilisez des techniques de débogage. 5) Optimiser les performances et suivre les meilleures pratiques.

Comment fusionner les éléments du tableau avec le même ID dans un seul objet en JavaScript? Lors du traitement des données, nous rencontrons souvent la nécessité d'avoir le même ID ...

Explorez la mise en œuvre de la fonction de glisser et de réglage du panneau de type VScode dans le frontal. Dans le développement frontal, comment implémenter un VScode comme ...
