Hooks 
En react, les hooks sont des fonctions (systematiquement commençant par use) qui permettent de gérer l'état et les effets secondaires des composants. La librairie integre déjà un ensemble de hooks indispensable, et il est possible de créer ses propres hooks.
useState 
https://react.dev/reference/react/useState
Comme vu precedement, les variables locales des composants sont réinitialisées à chaque rendu. Pour conserver une valeur entre les rendus, on peut utiliser le hook useState. Celui ci retourne une paire de valeurs: la valeur courante et une fonction pour la modifier.
Lorsqu'une variable créée avec useState est modifiée avec son set..., tous les composants affichant cette variable seront re-rendus.
function Counter() {
    const [count, setCount] = useState(0);
    return <div>
        <p>Count is {count}</p>
        <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
}Attention: il ne faut pas modifier directement l'état d'une variable (count ici)
Pour modifier des valeurs dans un objet ou un tableau, on peut déstructurer, ou utiliser le prototype `set...(prevState => newState):
const [data, setData] = useState({
    value: 0,
    name: "John"
});
setData({
    ...data,
    value: data.value + 1
})
setData(prev => ({
    ...prev,
    value: prev.value + 1
}))useEffect 
https://react.dev/reference/react/useEffect
Ce hook servira a executer des actions qui auront des effets secondaires, tel que des appels API, des événements, des animations, etc.
Il prend en paramètre une fonction et un tableau de valeurs. La fonction sera appelée à chaque fois qu'une des valeurs du tableau change. Si un tableau vide est passé, la fonction sera appelée une seule fois après que le composant ait été créé.
Cette fonction peut retourner une fonction de nettoyage qui sera appelée lorsque l'effet sera relancé, ou lorsque le composant sera démonté.
useEffect(() => {
    console.log("Component mounted")
    return () => console.log("Component unmounted") // optionnel
}, [])
const [count, setCount] = useState(0);
useEffect(() => {
    console.log("count changed", count)
}, [count])Attention: Toutes les variables qui peuvent potentiellement changer dans la fonction doivent être dans le tableau de dépendances.
useMemo 
https://react.dev/reference/react/useMemo
useMemo est un Hook React qui vous permet de mettre en cache le résultat d’un calcul d’un rendu à l’autre. Comme useEffect, il prend en paramètre une fonction et un tableau de valeurs. La fonction sera appelée à chaque fois qu'une des valeurs du tableau change.
Cela evite d'effectuer le même calcul à chaque rendu du composant.
const memoizedValue = useMemo(() => {
    return expensiveComputation(a, b);
}, [a, b]);useCallback 
https://react.dev/reference/react/useCallback
useCallback est similaire à useMemo, sauf qu'il conserve une fonction plutot qu'une valeur.
const memoizedCallback = useCallback(() => {
    doSomething(a, b);
}, [a, b]);Cela permet d'optimiser les performances des composants et des hooks personnalisés en évitant de re-créer les fonctions à chaque rendu.
useRef 
https://react.dev/reference/react/useRef
useRef est un Hook React qui vous permet de créer une référence vers une valeur qui n'a pas d'incidence sur le rendu du composant. Si cette valeur change, le rendu ne sera pas ré-executé. Il est souvent utiliser pour stocker des references vers des elements du DOM
const intervalRef = useRef(null);  
const inputRef = useRef(null);
function handleClick() {
    inputRef.current.focus();
}
useEffect(() => {
    intervalRef.current = setInterval(() => {
        console.log("tick");
    }, 1000);
    return () => clearInterval(intervalRef.current);
}, []);
return <div>
    <input ref={inputRef} />
    <button onClick={handleClick}>Focus</button>
</div>useContext 
https://react.dev/reference/react/useContext
useContext est un Hook React qui vous permet d'acceder aux données d'un contexte.
const MyContext = createContext(null);
function App() {
    return (
        <MyContext.Provider value="Hello">
            <MyComponent />
        </MyContext.Provider>
    )
}
function MyComponent() {
    const value = useContext(MyContext);
    return <div>{value}</div>;
}Les contextes permettent de partager des données entre les composants sans avoir à les passer explicitement à chaque composant en tant que props.
Hooks personnalisés 
Il est possible de créer ses propres hooks. Pour cela, il faut suivre les règles de hooks et utiliser les hooks existants.
function useCounter() {
    const [count, setCount] = useState(0)
    function increment() {
        setCount(count + 1)
    }
    useEffect(() => {
        console.log("count changed", count)
    }, [count])
    return [count, increment]
}
function MyComponent() {
    const [count, increment] = useCounter();
    return <div>
        <p>Count is {count}</p>
        <button onClick={increment}>Increment</button>
    </div>
}Rule of hooks 
Les hooks doivent impérativement être utilisés à la racine d'un composant ou d'un autre hook, c'est à dire jamais de manière conditionnelle ou imbriquée.
function Counter() {
  const [count, setCount] = useState(0); // ✅
  if(count > 10) {
    const [count2, setCount2] = useState(0); // ❌
  }
  for (let i = 0; i < 10; i++) {
    const theme = useContext(ThemeContext); // ❌
  }
  if(count > 10) {
    return <div>Count is greater than 10</div>
  }
  const [count3, setCount3] = useState(0); // ❌
  //...
}