Le hook useCallback mémorise la fonction elle-même, pas sa valeur de retour. useCallback met en cache la référence de la fonction
Une fonction déclarée à l'intérieur d'un composant est recréée à chaque rendu, semblable à une variable. La différence est qu'il est rendu avec une référence différente à chaque fois. Alors,
Un useEffect dépendant de cette fonction s'exécutera à nouveau à chaque rendu :
import React, { useState, useEffect, useCallback } from 'react'; // Parent Component const ParentComponent = () => { const [count, setCount] = useState(0); const [text, setText] = useState(""); // Function declared inside the component const handleClick = () => { setCount(count + 1); }; // useEffect depending on handleClick useEffect(() => { console.log("handleClick changed, running useEffect"); }, [handleClick]); return ( <div> <button onClick={handleClick}>Increment Count</button> <p>Count: {count}</p> <ChildComponent handleClick={handleClick} /> </div> ); }; // Child Component const ChildComponent = React.memo(({ handleClick }) => { console.log("ChildComponent re-rendered"); return <button onClick={handleClick}>Child Increment</button>; }); export default ParentComponent;
Une chose similaire se produit avec les composants enfants :
Lorsque nous avons un composant avec une logique de rendu coûteuse ou « lente » en tant qu'enfant d'un autre composant, chaque fois que le composant parent est rendu, tous ses enfants sont également restitués.
Pour éviter ces nouveaux rendus inutiles, nous pouvons utiliser React.memo. Ce composant d'ordre supérieur met en cache le composant enfant, garantissant qu'il ne sera restitué que si ses accessoires changent réellement. Cependant, il y a un problème subtil lors du passage de fonctions comme accessoires, ce qui amène l'enfant à refaire le rendu même s'il ne devrait pas.
Le problème avec les références de fonctions
Imaginez que nous ayons un SlowComponent en tant qu'enfant d'App. Dans App, nous avons un état qui change lorsque vous cliquez sur un bouton, déclenchant un nouveau rendu de l'application. Bien que nous ne modifions pas les accessoires de SlowComponent, il s'affiche toujours à chaque clic.
Pourquoi ? À chaque rendu, la fonction handleClick est recréée avec une nouvelle référence, que React interprète comme un accessoire modifié, provoquant le nouveau rendu de SlowComponent. Pour résoudre ce problème, nous utilisons le hook useCallback pour mettre en cache la référence de la fonction dans les rendus.
Solution avec useCallback
En enveloppant handleClick dans useCallback, nous disons à React de le recréer uniquement lorsque des dépendances spécifiques changent. Voici la syntaxe :
const cachedFn = useCallback(fn, [dependencies]);
Application de useCallback dans notre exemple
Voyons comment nous utiliserions useCallback pour optimiser notre composant App :
import React, { useState, useCallback } from "react"; const App = () => { const [count, setCount] = useState(0); const [value, setValue] = useState(""); // Wrapping handleClick with useCallback to cache its reference const handleClick = useCallback(() => { setValue("Kunal"); }, [setValue]); return ( <div> <button onClick={() => setCount(count + 1)}>Increment Count</button> <p>Count: {count}</p> <SlowComponent handleClick={handleClick} /> </div> ); }; const SlowComponent = React.memo(({ handleClick }) => { // Intentially making the component slow for (let i = 0; i < 1000000000; i++) {} console.log("SlowComponent re-rendered"); return <button onClick={handleClick}>Click me in SlowComponent</button>; }); export default App;
Quand utiliser useCallback
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!