Hướng Dẫn Sử Dụng useEffect
Trong React: Bí Quyết, Lỗi Phổ Biến Và Xu Hướng JavaScript Hiện Đại
Hook useEffect
trong React là một phần cốt lõi trong việc phát triển các component theo phương thức function, cho phép bạn xử lý các tác dụng phụ như lấy dữ liệu, thao tác với DOM và theo dõi các cập nhật. Mặc dù rất mạnh mẽ, useEffect
thường bị hiểu sai, dẫn đến việc tạo ra những vấn đề về hiệu suất cũng như các lỗi khó chịu trong ứng dụng.
Bài viết này sẽ hướng dẫn bạn những phương pháp hay nhất để sử dụng useEffect
, những lỗi phổ biến cần tránh, và cách mà JavaScript hiện đại có thể hỗ trợ để code React của bạn hiệu quả hơn.
useEffect
Là Gì?
useEffect
là một hook mà bạn có thể sử dụng để thực hiện các tác dụng phụ trong các function component. Nó thay thế cho các phương thức vòng đời truyền thống như componentDidMount
, componentDidUpdate
, và componentWillUnmount
. Cú pháp tổng quan của useEffect
như sau:
useEffect(() => {
// Logic thực hiện tác dụng phụ
return () => {
// Logic dọn dẹp (tuỳ chọn)
};
}, [dependencies]);
Các Phương Pháp Hay Nhất Cho useEffect
1. Sử Dụng Mảng Phụ Thuộc Đúng Cách
Mảng phụ thuộc rất quan trọng vì nó đảm bảo rằng hiệu ứng của bạn chỉ chạy khi các giá trị trong mảng thay đổi. Bạn cần bao gồm tất cả các biến được sử dụng trong hiệu ứng. Nếu bỏ qua các phụ thuộc, bạn có thể gặp lỗi hoặc nhận dữ liệu cũ.
Ví dụ:
useEffect(() => {
console.log(`Giá trị hiện tại là: ${count}`);
}, [count]); // Chạy khi `count` thay đổi
Để hỗ trợ bạn, hãy sử dụng công cụ lint như eslint-plugin-react-hooks
để tìm kiếm các phụ thuộc bị thiếu.
2. Phân Tách Các Mối Quan Tâm Qua Nhiều Hiệu Ứng
Mỗi useEffect
nên chỉ chịu trách nhiệm cho một mối quan tâm duy nhất. Nếu bạn kết hợp nhiều trách nhiệm trong một hiệu ứng, điều này sẽ làm cho code của bạn khó gỡ lỗi và bảo trì hơn.
Ví dụ:
useEffect(() => {
console.log("Component đã được gán");
}, []);
useEffect(() => {
document.title = `Giá trị mới: ${count}`;
}, [count]);
3. Dọn Dẹp Các Tác Dụng Phụ
Để tránh tình trạng rò rỉ bộ nhớ, bạn cần dọn dẹp các tác dụng phụ như đăng ký sự kiện hoặc bộ hẹn giờ khi component bị hủy hoặc khi hiệu ứng chạy lại.
Ví dụ:
useEffect(() => {
const timer = setInterval(() => {
console.log("Bộ hẹn giờ đang chạy");
}, 1000);
return () => clearInterval(timer); // Logic dọn dẹp
}, []);
4. Tránh Việc Sử Dụng useEffect
Quá Nhiều
Không phải tất cả logic đều cần đến useEffect
. Ví dụ, bạn không cần sử dụng useEffect
cho trạng thái dẫn xuất hoặc cho các phép toán đơn giản.
Ví dụ sai:
useEffect(() => {
setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);
Ví dụ tốt:
const fullName = `${firstName} ${lastName}`;
5. Sử Dụng Custom Hooks Để Tái Sử Dụng Hiệu Ứng
Trích xuất logic của các hiệu ứng lặp lại thành các custom hooks để đơn giản hóa các component của bạn và thúc đẩy việc tái sử dụng code.
Ví dụ:
const useFetchData = (url) => {
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const response = await fetch(url);
const result = await response.json();
setData(result);
};
fetchData();
}, [url]);
return data;
};
Cách sử dụng:
const data = useFetchData("/api/data");
Những Lỗi Phổ Biến Khi Sử Dụng useEffect
1. Quên Các Phụ Thuộc
Việc quên các phụ thuộc sẽ khiến hiệu ứng sử dụng các giá trị lỗi thời hoặc bỏ qua những cập nhật cần thiết. Hãy chắc chắn rằng bạn đã liệt kê mọi biến được sử dụng trong hiệu ứng.
2. Tạo Vòng Lặp Vô Hạn
Việc cập nhật trạng thái bên trong một hiệu ứng mà không có điều kiện thích hợp có thể gây ra vòng lặp render vô hạn.
Ví dụ không tốt:
useEffect(() => {
setCount(count + 1); // Gây ra render vô hạn
}, [count]);
Sửa lại như sau:
useEffect(() => {
if (count < 10) {
setCount(count + 1);
}
}, [count]);
3. Rò Rỉ Bộ Nhớ
Việc quên dọn dẹp các hiệu ứng như trình nghe sự kiện hoặc bộ hẹn giờ có thể dẫn đến tình trạng rò rỉ bộ nhớ, đặc biệt là trong các ứng dụng lớn hơn.
Ví dụ không tốt:
useEffect(() => {
window.addEventListener("resize", handleResize);
}, []); // Không dọn dẹp
Sửa lại như sau:
useEffect(() => {
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
4. Làm Phức Tạp Các Hiệu Ứng
Hãy tránh lạm dụng useEffect
cho những tác vụ có thể xử lý trực tiếp trong quá trình render hoặc với trạng thái dẫn xuất.
Hỗ Trợ Từ JavaScript Hiện Đại Trong useEffect
React và JavaScript hiện đại hợp tác chặt chẽ với nhau. Các tính năng như async/await
, đối tượng phân tách cấu trúc (destructuring) và chuỗi tùy chọn (optional chaining) giúp cho logic trong useEffect
của bạn trở nên rõ ràng và hiệu quả hơn.
Ví dụ: Sử dụng async/await
trong hiệu ứng
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch("/api/data");
const result = await response.json();
setData(result);
} catch (error) {
console.error("Có lỗi xảy ra khi fetching data:", error);
}
};
fetchData();
}, []);
Kết Luận
Việc nắm vững cách sử dụng useEffect
là rất quan trọng để xây dựng các ứng dụng React mạnh mẽ và hiệu quả. Bằng cách tuân theo các phương pháp tốt nhất, tránh những lỗi thường gặp, và tận dụng các tính năng của JavaScript hiện đại, bạn có thể viết code sạch sẽ, dễ bảo trì và tối ưu hóa hiệu suất ứng dụng của mình.
source: viblo