Reageerhaak useCallback
_
De React useCallback
Hook retourneert een in het geheugen opgeslagen callback-functie.
Beschouw memo's als het cachen van een waarde, zodat deze niet opnieuw hoeft te worden berekend.
Dit stelt ons in staat om resource-intensieve functies te isoleren, zodat ze niet automatisch op elke render worden uitgevoerd.
The useCallback
Hook wordt alleen uitgevoerd wanneer een van zijn afhankelijkheden wordt bijgewerkt.
Dit kan de prestaties verbeteren.
De useCallback
en useMemo
Hooks zijn vergelijkbaar. Het belangrijkste verschil is dat useMemo
een gememoriseerde waarde wordt useCallback
geretourneerd en een gememoriseerde functie wordt geretourneerd . U kunt meer leren over useMemo in het hoofdstuk useMemo .
Probleem
Een reden om te gebruiken useCallback
is om te voorkomen dat een component opnieuw wordt weergegeven, tenzij de rekwisieten zijn gewijzigd.
In dit voorbeeld zou u kunnen denken dat de Todos
component niet opnieuw wordt weergegeven, tenzij de todos
wijziging:
Dit is een soortgelijk voorbeeld als dat in de sectie React.memo .
Voorbeeld:
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);
Probeer dit uit te voeren en klik op de knop voor het verhogen van het aantal.
U zult merken dat het Todos
onderdeel opnieuw wordt weergegeven, zelfs als het todos
niet verandert.
Waarom werkt dit niet? We gebruiken memo
, dus de Todos
component mag niet opnieuw worden weergegeven, omdat noch de todos
status noch de addTodo
functie veranderen wanneer de telling wordt verhoogd.
Dit komt door iets dat "referentiële gelijkheid" wordt genoemd.
Elke keer dat een component opnieuw wordt weergegeven, worden de functies ervan opnieuw gemaakt. Hierdoor is de addTodo
functie daadwerkelijk veranderd.
Gecertificeerd!
$95 INSCHRIJVEN
Oplossing
Om dit op te lossen, kunnen we de useCallback
haak gebruiken om te voorkomen dat de functie opnieuw wordt gemaakt, tenzij dat nodig is.
Gebruik de useCallback
Hook om te voorkomen dat de Todos
component onnodig opnieuw wordt weergegeven:
Voorbeeld:
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);
Nu wordt de Todos
component alleen opnieuw weergegeven als de todos
prop verandert.