Bereaksi useCallback
Kait
React useCallback
Hook mengembalikan fungsi callback yang telah di memo.
Pikirkan memoisasi sebagai caching nilai sehingga tidak perlu dihitung ulang.
Hal ini memungkinkan kami untuk mengisolasi fungsi intensif sumber daya sehingga tidak akan berjalan secara otomatis pada setiap render.
Hook useCallback
hanya berjalan ketika salah satu dependensinya diperbarui.
Hal ini dapat meningkatkan kinerja.
The useCallback
dan useMemo
Hooks serupa. Perbedaan utama adalah useMemo
mengembalikan nilai memo dan useCallback
mengembalikan fungsi memo . Anda dapat mempelajari lebih lanjut tentang useMemo di bab useMemo .
Masalah
Salah satu alasan untuk menggunakan useCallback
adalah untuk mencegah komponen dari re-rendering kecuali props-nya telah berubah.
Dalam contoh ini, Anda mungkin berpikir bahwa Todos
komponen tidak akan dirender ulang kecuali todos
perubahannya:
Ini adalah contoh yang mirip dengan yang ada di bagian React.memo .
Contoh:
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);
Coba jalankan ini dan klik tombol hitung kenaikan.
Anda akan melihat bahwa Todos
komponen merender ulang bahkan ketika todos
tidak berubah.
Mengapa ini tidak berhasil? Kami menggunakan memo
, jadi Todos
komponen tidak boleh dirender ulang karena baik todos
status maupun addTodo
fungsi tidak berubah saat hitungan bertambah.
Ini karena sesuatu yang disebut "kesetaraan referensial".
Setiap kali komponen dirender ulang, fungsinya akan dibuat ulang. Karena itu, addTodo
fungsinya sebenarnya telah berubah.
Dapatkan Sertifikasi!
$95 DAFTAR
Larutan
Untuk memperbaikinya, kita dapat menggunakan useCallback
pengait untuk mencegah fungsi dibuat ulang kecuali diperlukan.
Gunakan useCallback
Hook untuk mencegah Todos
komponen dirender ulang secara tidak perlu:
Contoh:
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);
Sekarang Todos
komponen hanya akan dirender ulang ketika todos
prop berubah.