Reagovat useCallback
Hook
React useCallback
Hook vrací funkci zpětného volání uloženou v paměti.
Pamatování si představte jako ukládání hodnoty do mezipaměti, aby ji nebylo nutné přepočítávat.
To nám umožňuje izolovat funkce náročné na zdroje, aby se automaticky nespouštěly při každém renderu.
Hook běží pouze tehdy, když se useCallback
aktualizuje jedna z jeho závislostí.
To může zlepšit výkon.
The useCallback
a useMemo
Hooks jsou podobné. Hlavní rozdíl je v tom, že useMemo
vrací zapamatovanou hodnotu a useCallback
vrací zapamatovanou funkci . Více o useMemo se můžete dozvědět v kapitole useMemo .
Problém
Jedním z důvodů použití useCallback
je zabránit komponentě v opětovném vykreslení, pokud se její podpěry nezměnily.
V tomto příkladu si můžete myslet, že Todos
komponenta se nebude znovu vykreslovat, pokud nedojde ke todos
změně:
Toto je podobný příklad jako v sekci React.memo .
Příklad:
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);
Zkuste to spustit a klikněte na tlačítko zvýšení počtu.
Všimnete si, že se Todos
komponenta znovu vykresluje, i když se todos
nezmění.
Proč to nefunguje? Používáme memo
, takže Todos
komponenta by se neměla znovu vykreslovat, protože ani todos
stav ani addTodo
funkce se nemění, když se počet zvyšuje.
Je to kvůli něčemu, čemu se říká „referenční rovnost“.
Pokaždé, když se komponenta znovu vykreslí, její funkce se znovu vytvoří. Z tohoto důvodu se addTodo
funkce skutečně změnila.
Získejte certifikaci!
95 $ PŘIHLÁSIT SE
Řešení
Abychom to napravili, můžeme pomocí useCallback
háku zabránit opětovnému vytvoření funkce, pokud to není nutné.
Použijte useCallback
Hook, abyste zabránili Todos
zbytečnému opětovnému vykreslování komponenty:
Příklad:
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);
Nyní se Todos
komponenta znovu vykreslí pouze při změně todos
podpěry.