0

useEffect trong React: Bí quyết sử dụng, những lỗi thường gặp và góc nhìn JavaScript hiện đại

Hook useEffect của React là nền tảng cốt lõi trong việc phát triển component theo hướng function, cho phép xử lý các hiệu ứng phụ như lấy dữ liệu, thao tác DOM và đăng ký. Mặc dù mạnh mẽ, useEffect thường bị hiểu sai, dẫn đến tắc nghẽn hiệu suất và lỗi khó chịu.

Bài viết này sẽ khám phá các phương pháp hay nhất để sử dụng useEffect, những lỗi thường gặp cần tránh và cách JavaScript hiện đại có thể giúp code React của bạn hiệu quả hơn.

useEffect là gì?

useEffect là một hook cho phép bạn thực hiện các tác dụng phụ trong các function component. Nó là sự thay thế của React cho các phương thức vòng đời như componentDidMount, componentDidUpdatecomponentWillUnmount. Tổng quan về cú pháp:

useEffect(() => {
  // Effect logic
  return () => {
    // Cleanup logic (optional)
  };
}, [dependencies]);

Best practice cho useEffect

1. Sử dụng Mảng phụ thuộc chính xác

Mảng phụ thuộc đảm bảo rằng hiệu ứng của bạn chỉ chạy khi các giá trị cụ thể thay đổi. Luôn bao gồm tất cả các biến được sử dụng bên trong hiệu ứng. Thiếu phụ thuộc có thể dẫn đến lỗi hoặc dữ liệu cũ.

Ví dụ:

useEffect(() => {
  console.log(`Current count is: ${count}`);
}, [count]); // Runs only when `count` changes

Mẹo hữu ích cho bạn: Sử dụng một công cụ lint như eslint-plugin-react-hooks để tìm lấy các phụ thuộc bị thiếu.

2. Phân tách các Mối quan tâm bằng nhiều hiệu ứng

Mỗi useEffect nên xử lý một mối quan tâm duy nhất. Việc kết hợp nhiều trách nhiệm trong một hiệu ứng sẽ khiến code của bạn khó gỡ lỗi và bảo trì hơn.

Ví dụ:

useEffect(() => {
  console.log("Component mounted");
}, []);

useEffect(() => {
  document.title = `New count: ${count}`;
}, [count]);

3. Luôn dọn dẹp các tác dụng phụ

Để tránh rò rỉ bộ nhớ, hãy dọn dẹp các tác dụng phụ như đăng ký hoặc bộ hẹn giờ khi component bị hủy hoặc hiệu ứng chạy lại.

Ví dụ:

useEffect(() => {
  const timer = setInterval(() => {
    console.log("Timer running");
  }, 1000);

  return () => clearInterval(timer); // Cleanup
}, []);

4. Tránh sử dụng quá mức useEffect

Không phải tất cả logic đều thuộc về useEffect. Ví dụ: bạn không cần useEffect cho trạng thái dẫn xuất hoặc các phép tính đơn giản.

Ví dụ tệ mà bạn không nên làm:

useEffect(() => {
  setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);

Còn đây là ví dụ tốt nên làm theo:

const fullName = `${firstName} ${lastName}`;

5. Sử dụng Custom Hooks cho các Hiệu ứng có thể tái sử dụng

Trích xuất logic useEffect lặp lại thành 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 thường gặp của useEffect

1. Quên phụ thuộc

Việc thiếu phụ thuộc có thể khiến hiệu ứng của bạn sử dụng các giá trị lỗi thời hoặc bỏ qua các cập nhật cần thiết. Luô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ó các điều kiện thích hợp có thể tạo ra các vòng lặp render vô hạn.

Ví dụ không tốt:

useEffect(() => {
  setCount(count + 1); // Triggers re-render, causing an infinite loop
}, [count]);

Hãy sửa lại nó như thế này:

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 lắng nghe sự kiện hoặc bộ hẹn giờ có thể dẫn đến 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);
}, []); // Cleanup missing

Hãy sửa lại như sau:

useEffect(() => {
  window.addEventListener("resize", handleResize);
  return () => window.removeEventListener("resize", handleResize);
}, []);

4. Làm phức tạp hóa các Hiệu ứng

Đừng lạm dụng useEffect cho các tác vụ có thể được xử lý trực tiếp trong quá trình render hoặc với trạng thái dẫn xuất.

JavaScript hiện đại hỗ trợ như thế nào trong useEffect

React và JavaScript hiện đại song hành cùng nhau. Các tính năng như async/await, phân tách cấu trúc và chuỗi tùy chọn có thể làm cho logic useEffect của bạ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("Error fetching data:", error);
    }
  };
  fetchData();
}, []);

Kết luận

Nắm vững useEffect là điều cần thiết để xây dựng các ứng dụng React mạnh mẽ. Bằng cách làm theo các phương pháp hay nhất, tránh các 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, dễ bảo trì và hiệu quả.


All rights reserved

Bình luận

Đang tải thêm bình luận...
Avatar
0
Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí