useCallback
là một React Hook dùng để tạo ra một hàm callback mới và giữ nguyên giá trị của hàm đó qua các lần render. Nó thường được sử dụng để tối ưu hiệu suất bằng cách tránh việc tạo lại các hàm callback mỗi khi component render lại. Khi một hàm callback được tạo bởi useCallback
, nó sẽ được gắn liền với các dependencies mà bạn cung cấp, và chỉ thay đổi khi các dependencies thay đổi. Dưới đây là một ví dụ về cách sử dụng useCallback
:
jsx
import React, { useState, useCallback } from 'react';
function Button({ onClick }) {
return <button onClick={onClick}>Click me</button>;
}
function App() {
const [count, setCount] = useState(0);
// Sử dụng useCallback để tạo hàm callback mới khi count thay đổi
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<p>Count: {count}</p>
<Button onClick={handleClick} />
</div>
);
}
export default App;
Trong ví dụ trên, chúng ta sử dụng useCallback
để tạo hàm handleClick
. Khi component render lại, handleClick
không bị tạo lại mà được giữ nguyên giá trị qua các lần render. Điều này có lợi cho hiệu suất, đặc biệt khi component cha truyền hàm này xuống các thành phần con như Button
. Nếu không sử dụng useCallback
, mỗi lần render mới sẽ tạo ra một hàm callback mới, dẫn đến việc Button
cần render lại mỗi khi cha render lại.
Chú ý rằng việc sử dụng useCallback
không nên quá tối ưu hoá sớm. Hãy sử dụng nó khi bạn thực sự cần tối ưu hiệu suất và đã xác định được rằng việc tạo lại hàm callback thường xuyên đang gây ra vấn đề.
Dưới đây là một ví dụ cụ thể về cách sử dụng useCallback
trong một ứng dụng React để tối ưu việc render lại các thành phần con:
jsx
import React, { useState, useCallback } from 'react';
function ChildComponent({ onClick }) {
console.log('ChildComponent rendering...');
return <button onClick={onClick}>Click me</button>;
}
function ParentComponent() {
const [count, setCount] = useState(0);
// Sử dụng useCallback để tạo hàm callback mới khi count thay đổi
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
console.log('ParentComponent rendering...');
return (
<div>
<p>Count: {count}</p>
<ChildComponent onClick={handleClick} />
</div>
);
}
function App() {
return (
<div>
<h1>Optimizing with useCallback</h1>
<ParentComponent />
</div>
);
}
export default App;
Trong ví dụ này, chúng ta có hai thành phần: ChildComponent
và ParentComponent
. ChildComponent
nhận một hàm callback onClick
từ ParentComponent
và render một nút.
Khi ParentComponent
không sử dụng useCallback
để tạo hàm callback handleClick
, mỗi lần ParentComponent
render lại, hàm handleClick
cũng bị tạo lại. Điều này dẫn đến việc khi ParentComponent
render lại, ChildComponent
cũng cần render lại vì prop onClick
đã thay đổi.
Khi chúng ta sử dụng useCallback
để tạo hàm callback, chúng ta đảm bảo rằng hàm handleClick
không bị tạo lại mỗi lần ParentComponent
render lại. Như kết quả, ChildComponent
không cần render lại mỗi khi ParentComponent
render lại, giúp tối ưu hiệu suất của ứng dụng. Trên đây là giới thiệu về useCallback trong React JS.