Crochet de useCallback
réaction
Le React useCallback
Hook renvoie une fonction de rappel mémorisée.
Considérez la mémorisation comme la mise en cache d'une valeur afin qu'elle n'ait pas besoin d'être recalculée.
Cela nous permet d'isoler les fonctions gourmandes en ressources afin qu'elles ne s'exécutent pas automatiquement à chaque rendu.
Le useCallback
crochet ne s'exécute que lorsque l'une de ses dépendances est mise à jour.
Cela peut améliorer les performances.
Les crochets useCallback
et useMemo
sont similaires. La principale différence est que useMemo
renvoie une valeur mémorisée et useCallback
renvoie une fonction mémorisée . Vous pouvez en savoir plus sur useMemo dans le chapitre useMemo .
Problème
L'une des raisons de l'utiliser useCallback
est d'empêcher un composant de se restituer à moins que ses accessoires n'aient changé.
Dans cet exemple, vous pourriez penser que le Todos
composant ne sera pas restitué à moins que le todos
changement :
Ceci est un exemple similaire à celui de la section React.memo .
Exemple:
index.js
import { useState } from "react";
import ReactDOM from "react-dom";
import Todos from "./Todos";
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState([]);
const increment = () => {
setCount((c) => c + 1);
};
const addTodo = () => {
setTodos((t) => [...t, "New Todo"]);
};
return (
<>
<Todos todos={todos} addTodo={addTodo} />
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
</div>
</>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
Todos.js
import { memo } from "react";
const Todos = ({ todos, addTodo }) => {
console.log("child render");
return (
<>
<h2>My Todos</h2>
{todos.map((todo, index) => {
return <p key={index}>{todo}</p>;
})}
<button onClick={addTodo}>Add Todo</button>
</>
);
};
export default memo(Todos);
Essayez de l'exécuter et cliquez sur le bouton d'incrémentation du nombre.
Vous remarquerez que le Todos
composant restitue même lorsque le todos
ne change pas.
Pourquoi cela ne fonctionne-t-il pas ? Nous utilisons memo
, donc le Todos
composant ne doit pas être rendu à nouveau puisque ni l' todos
état ni la addTodo
fonction ne changent lorsque le nombre est incrémenté.
C'est à cause de ce qu'on appelle "l'égalité référentielle".
Chaque fois qu'un composant est restitué, ses fonctions sont recréées. Pour cette raison, la addTodo
fonction a en fait changé.
Obtenir une certification!
95 $ S'INSCRIRE
Solution
Pour résoudre ce problème, nous pouvons utiliser le useCallback
crochet pour empêcher la recréation de la fonction, sauf si nécessaire.
Utilisez le useCallback
crochet pour empêcher le Todos
composant de se restituer inutilement :
Exemple:
index.js
import { useState, useCallback } from "react";
import ReactDOM from "react-dom";
import Todos from "./Todos";
const App = () => {
const [count, setCount] = useState(0);
const [todos, setTodos] = useState([]);
const increment = () => {
setCount((c) => c + 1);
};
const addTodo = useCallback(() => {
setTodos((t) => [...t, "New Todo"]);
}, [todos]);
return (
<>
<Todos todos={todos} addTodo={addTodo} />
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
</div>
</>
);
};
ReactDOM.render(<App />, document.getElementById('root'));
Todos.js
import { memo } from "react";
const Todos = ({ todos, addTodo }) => {
console.log("child render");
return (
<>
<h2>My Todos</h2>
{todos.map((todo, index) => {
return <p key={index}>{todo}</p>;
})}
<button onClick={addTodo}>Add Todo</button>
</>
);
};
export default memo(Todos);
Désormais, le Todos
composant ne sera restitué que lorsque l' todos
accessoire changera.