Contents

useEffect, useLayoutEffect và useEffectEvent: So sánh các móc tìm nạp dữ liệu trong React

React hook là một cách mạnh mẽ để quản lý các tác dụng phụ trong các thành phần React. Ba trong số các hook phổ biến nhất để xử lý các tác dụng phụ là useEffect, useLayoutEffect và useEffectEvent. Mỗi móc đều có trường hợp sử dụng riêng, vì vậy việc chọn đúng loại móc cho công việc là điều cần thiết.

Hook useEffect

chức năng hiển thị hiệu ứng và danh sách phụ thuộc.

Hàm hiệu ứng đóng gói mã chịu trách nhiệm tạo ra hiệu ứng phụ, trong khi mảng phụ thuộc chỉ ra khi nào hàm nói trên sẽ được thực thi. Trong trường hợp mảng phụ thuộc vẫn không có nội dung, hàm hiệu ứng sẽ chỉ thực thi trong quá trình hiển thị thành phần ban đầu. Ngược lại, nếu mảng phụ thuộc chứa bất kỳ thay đổi nào, hàm hiệu ứng sẽ được kích hoạt để chạy lại sau mỗi lần sửa đổi.

Thật vậy, có thể tìm thấy một minh họa điển hình về việc sử dụng hook useEffect để truy xuất dữ liệu như sau:

 import React from "react";

function App() {
  const [data, setData] = React.useState([]);

  React.useEffect(() => {
    fetch("<https://jsonplaceholder.typicode.com/posts>")
      .then((response) => response.json())
      .then((data) => setData(data));
  }, []);

  return (
    <div className="app">
      {data.map((item) => (
        <div key={item.id}>{item.title}</div>
      ))}
    </div>
  );
}

export default App;

Ví dụ này giới thiệu một thành phần React chức năng, được gọi là thành phần “Ứng dụng”, sử dụng hook “useEffect” để truy xuất dữ liệu từ API bên ngoài. Cụ thể, trình xử lý hiệu ứng được liên kết với hook “useEffect” sẽ tìm nạp thông tin mẫu từ API JSONPlaceholder, xử lý phản hồi JSON và sau đó cập nhật trạng thái “dữ liệu” với dữ liệu thu được.

Có tính đến trạng thái hiện tại của dữ liệu ứng dụng của chúng tôi, ứng dụng sẽ hiển thị thuộc tính tiêu đề được liên kết với mọi mục tương ứng trong thông tin đó.

Đặc điểm của useEffect Hook

Ứng dụng này được thiết kế với mục đích hoạt động không đồng bộ và tích hợp chức năng này một cách nguyên bản, mang lại trải nghiệm liền mạch khi truy xuất dữ liệu.

Việc sử dụng hook useEffect được lên kế hoạch diễn ra sau khi hoàn thành quá trình kết xuất cho một thành phần nhất định, do đó đảm bảo rằng hook đó không cản trở hoặc cản trở giao diện người dùng trong khoảng thời gian này.

Lệnh cung cấp một cách tiếp cận hợp lý để thực hiện các nhiệm vụ dọn dẹp thông qua việc cung cấp một chức năng được gọi tự động sau khi hoàn thành trình nghe hoặc đăng ký. Chức năng như vậy có thể tỏ ra đặc biệt có lợi trong các tình huống mà việc đóng và giải phóng tài nguyên hiệu quả là điều tối quan trọng, chẳng hạn như trong các trường hợp liên quan đến người nghe hoặc đăng ký.

Hook useLayoutEffect

Việc sử dụng hook useLayoutEffect phản ánh chặt chẽ chức năng của hook useEffect; tuy nhiên, nó hoạt động đồng bộ sau tất cả các trường hợp thay đổi DOM. Do đó, chức năng này thực thi trước khả năng của trình duyệt trong việc hiển thị hình ảnh trực quan trên màn hình, do đó mang lại lợi ích cao cho các công việc đòi hỏi phải thao tác chính xác cấu trúc và thuộc tính kiểu dáng của Mô hình Đối tượng Tài liệu (DOM), bao gồm cả việc không giới hạn việc xác định kích thước của một phần tử cụ thể, điều chỉnh lại kích thước của một phần tử hoặc sắp xếp cách sắp xếp không gian của phần tử đó thông qua các kỹ thuật hoạt hình.

Bằng cách sử dụng hook useLayoutEffect , người ta có thể sửa đổi kích thước của thành phần nút như minh họa bên dưới:

 import React from "react";

function App() {
  const button = React.useRef();

  React.useLayoutEffect(() => {
    const { width } = button.current.getBoundingClientRect();

    button.current.style.width = `${width \+ 12}px`;
  }, []);

  return (
    <div className="app">
      <button ref={button}>Click Me</button>
    </div>
  );
}

export default App;

Đoạn mã nói trên mở rộng kích thước của thành phần nút lên 12 đơn vị bằng cách sử dụng tiện ích chức năng useLayoutEffect. Do đó, cấu hình này đảm bảo rằng chiều rộng đã điều chỉnh sẽ được áp dụng cho nút trước khi nó xuất hiện trực quan trên thiết bị hiển thị của người dùng.

Đặc điểm của useLayoutEffect Hook

Việc thực thi đồng bộ mã JavaScript đảm bảo rằng hoạt động diễn ra theo cách tuần tự mà không có bất kỳ sự gián đoạn nào đối với giao diện người dùng. Tuy nhiên, cách tiếp cận này có thể dẫn đến sự chậm trễ hoặc tắc nghẽn giao diện người dùng do tính chất tốn thời gian của một số hoạt động nhất định.

Hoạt động Đọc/Ghi DOM được thiết kế lý tưởng để truy cập ngay vào Mô hình Đối tượng Tài liệu cho cả việc đọc và ghi dữ liệu, đặc biệt khi ưu tiên tính hiệu quả trong việc quan sát các sửa đổi trước quá trình vẽ lại của trình duyệt.

Hook useEffectEvent

Việc sử dụng hook useEffectEvent được coi là một giải pháp hiệu quả cho các vấn đề phụ thuộc đầy thách thức vốn có trong hook useEffect thông thường. Có vẻ như những người thành thạo cách hoạt động của useEffect có thể thấy mình đang vật lộn với sự phức tạp của mảng phụ thuộc của nó, đôi khi đòi hỏi phải đưa vào các phần tử vượt quá những gì hoàn toàn cần thiết để hoạt động bình thường.

Ví dụ:

 import React from "react";

function App() {
  const connect = (url) => {
    // logic for connecting to the url
  };

  const logConnection = (message, loginOptions) => {
    // logic for logging the connection details
  };

  const onConnected = (url, loginOptions) => {
    logConnection(`Connected to ${url}`, loginOptions);
  };

  React.useEffect(() => {
    const device = connect(url);
    device.onConnected(() => {
      onConnected(url);
    });

    return () => {
      device.disconnect();
    };
  }, [url, onConnected]);

  return <div></div>;
}

export default App;

Mã hiện tại giới thiệu chức năng của

Hàm hook useEffect bằng cách gọi phương thức connect và thiết lập hàm gọi lại “onConnected” không đồng bộ sẽ được thực thi sau khi thiết bị kích hoạt sự kiện “onConnected”. Sau đó, lệnh gọi lại này sẽ thực thi một hành động nhật ký để tạo thông báo kết nối. Hơn nữa, nó cung cấp chức năng ngừng hoạt động, có hiệu lực khi ngắt kết nối thành phần, do đó chịu trách nhiệm cắt đứt kết nối với thiết bị.

DependencyArray kết hợp cả URL và trình xử lý sự kiện được gọi là “onConnected”. Mỗi khi thành phần Ứng dụng được hiển thị, nó sẽ tự động tạo ra chức năng cụ thể này. Do đó, hook React, “useEffect”, trải qua một quá trình lặp đi lặp lại trong đó mục tiêu chính của nó là cập nhật liên tục trạng thái của thành phần Ứng dụng.

Một trong những phương pháp hiệu quả để giải quyết vấn đề của vòng lặp useEffect là sử dụng hook useEffectEvent, cho phép đưa ra giải pháp hợp lý mà không tạo gánh nặng cho mảng phụ thuộc bằng các giá trị không chính đáng bổ sung.

 import React from "react";

function App() {
  const connect = (url) => {
    // logic for connecting to the URL
  };

  const logConnection = (message, loginOptions) => {
    // logic for logging the connection details
  };

  const onConnected = React.useEffectEvent((url, loginOptions) => {
    logConnection(`Connected to ${url}`, loginOptions);
  });

  React.useEffect(() => {
    const device = connect(url);
    device.onConnected(() => {
      onConnected(url);
    });

    return () => {
      device.disconnect();
    };
  }, [url]);

  return <div></div>;
}
export default App;

Bằng cách sử dụng hook useEffectEvent để bọc hàm onConnected, chúng tôi đảm bảo rằng các tham số messageloginOptions luôn cập nhật khi được chuyển đến hook useEffect. Do đó, cái sau không còn phụ thuộc vào cái trước hoặc bất kỳ thông số nào được cung cấp cho nó.

Khi sử dụng hook useEffect, có thể thuận lợi nếu dựa vào một giá trị cụ thể để kích hoạt hiệu ứng, mặc dù thực tế là hiệu ứng đó cần các giá trị bổ sung có thể không mong muốn làm phần phụ thuộc trong useEffect.

Đặc điểm của useEffectEvent Hook

Hệ thống này vượt trội trong việc xử lý các hậu quả do sự kiện gây ra.

Việc sử dụng hook useEffect không tương thích với các chức năng xử lý sự kiện như onClick , onChange , v.v., vì những sự kiện này được kích hoạt bởi tương tác của người dùng thay vì phụ thuộc phản ứng có thể được theo dõi các thay đổi bởi React.

Hook useEffect, một công cụ mạnh mẽ và linh hoạt để quản lý các tác dụng phụ trong các thành phần chức năng, vẫn là một tính năng thử nghiệm kể từ các phiên bản React cho đến 18. Cần lưu ý rằng tính khả dụng của nó có thể khác nhau giữa các bản phát hành hoặc bản dựng khác nhau của React.

Khi nào nên sử dụng móc nào?

Mỗi móc tìm nạp dữ liệu này có khả năng ứng dụng riêng, tùy thuộc vào trường hợp cụ thể.

Việc sử dụng hook useEffect trong React cung cấp giải pháp phù hợp để tìm nạp và cập nhật dữ liệu trong một thành phần, vì nó cho phép quản lý hiệu quả các hoạt động không đồng bộ trong khi vẫn duy trì cơ sở mã sạch sẽ và có tổ chức.

Khi thực hiện sửa đổi trực tiếp đối với Mô hình đối tượng tài liệu (DOM) là cần thiết theo cách yêu cầu hiển thị ngay lập tức các thay đổi, bạn nên sử dụng useLayoutEffect. Chức năng này cho phép xử lý hiệu quả các tác vụ đó bằng cách đảm bảo rằng các hành động đã chỉ định được thực thi sau lần hiển thị đầu tiên và trước khi xảy ra bất kỳ cập nhật hoặc chỉnh sửa tiếp theo nào.

Việc sử dụng hook useEffect cho các hoạt động nhẹ không gây ra nguy cơ cản trở giao diện người dùng, cho phép thực hiện chúng một cách dễ dàng và thuận tiện.

Việc sử dụng các tác dụng phụ theo hướng sự kiện có thể đạt được bằng cách sử dụng cả hook useEffectEvent để ghi lại và xử lý các sự kiện, cũng như hook useEffect để thực thi bất kỳ tác dụng phụ cần thiết nào để phản hồi lại các sự kiện đó.

Xử lý tác dụng phụ hiệu quả

Việc sử dụng móc React tiết lộ nhiều tiềm năng và hiểu được sự khác biệt giữa các móc useEffect, useLayoutEffect và useEffectEvent có thể ảnh hưởng đáng kể đến cách một người quản lý các tác dụng phụ và thao tác DOM. Điều bắt buộc là phải xem xét các điều kiện tiên quyết và phân nhánh cụ thể của các hook này để xây dựng các chương trình phần mềm lấy người dùng làm trung tâm.