Apprendre tous les hooks en React
28/11/2024 • Melvynx
Tu souhaites apprendre tous les hooks en React ? Ou plutôt tous les voir pour mieux comprendre comment ils fonctionnent ? Dans cet article, je vais t'expliquer chaque hook React avec un exemple concret pour m'assurer que tu les comprennes !
Le hook useState
te permet de stocker le state d'un composant. Le state est particulier car chaque fois qu'il change, il provoque un "re-render" qui signifie "le composant est recalculé par React pour connaître le nouveau rendu" afin de pouvoir afficher la nouvelle valeur.
On l'utilise comme ça :
// 👇 getter 👇 setter 👇 valeur initiale
const [count, setCount] = useState(0);
Voici un exemple concret :
Ce qu'il se passe quand le state change :
Si ta valeur initiale est coûteuse à calculer (comme un gros tableau ou un calcul complexe), tu peux passer une fonction d'initialisation à useState
:
// ❌ createInitialTodos est appelé à chaque render
const [todos, setTodos] = useState(createInitialTodos());
// ✅ createInitialTodos est appelé uniquement à l'initialisation
const [todos, setTodos] = useState(() => createInitialTodos());
Le hook useEffect
te permet d'exécuter du code en réaction à des changements dans ton composant. C'est parfait pour synchroniser ton composant avec des systèmes externes comme une API ou le localStorage.
useEffect(() => {
// Ce code s'exécute après le render
document.title = `Vous avez cliqué ${count} fois`;
}, [count]); // Uniquement si count change
Les cas d'utilisation principaux :
Voici un exemple correct avec cleanup :
useEffect(() => {
const subscription = api.subscribe((data) => {
// Faire quelque chose avec data
});
// Cleanup : se désabonner quand le composant est démonté
return () => {
subscription.unsubscribe();
};
}, []);
Le hook useContext
te permet d'accéder à des valeurs partagées dans ton arbre de composants sans avoir à passer les props manuellement à chaque niveau.
// 1. Créer le contexte
const ThemeContext = createContext("light");
// 2. Fournir une valeur
function App() {
return (
<ThemeContext.Provider value="dark">
<Button />
</ThemeContext.Provider>
);
}
// 3. Consommer la valeur
function Button() {
const theme = useContext(ThemeContext);
return <button className={theme}>Je suis {theme}</button>;
}
Voici un exemple :
Le hook useRef
te permet de garder une référence mutable qui persiste entre les renders. C'est très utile pour :
function TextInputWithFocusButton() {
const inputRef = useRef(null);
function handleClick() {
inputRef.current.focus();
}
return (
<>
<input ref={inputRef} type="text" />
<button onClick={handleClick}>Focus l'input</button>
</>
);
}
Exemple complet :
Ces hooks sont utilisés pour l'optimisation des performances :
useMemo
mémorise le résultat d'un calcul coûteuxuseCallback
mémorise une fonction// Mémoiser un calcul coûteux
const memoizedValue = useMemo(() => {
return computeExpensiveValue(a, b);
}, [a, b]);
// Mémoiser une fonction
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
Exemple complet :
Pour des states plus complexes, useReducer
te permet de gérer les mises à jour de state avec un pattern similaire à Redux :
const [state, dispatch] = useReducer(reducer, initialState);
// Dans ton reducer
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
throw new Error();
}
}
Exemple complet :
Le hook useActionState
est un nouveau hook disponible dans la version Canary de React qui te permet de gérer l'état d'un formulaire en fonction du résultat d'une action.
const [state, formAction, isPending] = useActionState(fn, initialState);
C'est particulièrement utile pour :
Exemple concret :
import { useActionState } from "react";
async function increment(previousState, formData) {
return previousState + 1;
}
function Counter() {
const [count, formAction] = useActionState(increment, 0);
return (
<form>
<p>Compteur: {count}</p>
<button formAction={formAction}>Incrémenter</button>
</form>
);
}
Le hook useOptimistic
est un nouveau hook qui te permet d'afficher un état optimiste pendant qu'une action est en cours. C'est super utile pour améliorer l'expérience utilisateur en montrant immédiatement le résultat attendu d'une action.
const [optimisticState, addOptimistic] = useOptimistic(state, updateFn);
Voici un exemple avec un bouton "J'aime" :
Le hook useInsertionEffect
est similaire à useEffect
, mais il s'exécute de manière synchrone avant toutes les mutations DOM. Il est principalement destiné aux bibliothèques CSS-in-JS.
useInsertionEffect(setup, dependencies?);
// Exemple d'utilisation dans une bibliothèque CSS-in-JS
useInsertionEffect(() => {
if (!isInserted.current) {
isInserted.current = true;
// Injecter des styles CSS dynamiques ici
}
});
Le hook useSyncExternalStore
te permet de souscrire à une source de données externe de manière sûre pour la concurrence.
const state = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?);
C'est particulièrement utile pour :
Exemple avec le statut en ligne/hors ligne :
Ces nouveaux hooks apportent des fonctionnalités puissantes pour gérer des cas d'usage spécifiques comme l'optimistic UI, la gestion de formulaires serveur et l'intégration avec des systèmes externes. N'hésite pas à les explorer pour améliorer l'expérience utilisateur de tes applications !
Les hooks sont la base de la gestion d'état et des effets de bord dans React. En comprenant bien chacun d'entre eux, tu pourras :
N'hésite pas à pratiquer avec chaque hook individuellement avant de les combiner. La pratique est la clé pour bien les maîtriser !