Cả hai đều chạy effect, nhưng tại các thời điểm khác nhau so với lúc trình duyệt vẽ (paint) — và sự khác biệt thời điểm đó chính là điểm mấu chốt.
Cả hai đều chạy effect, nhưng tại các thời điểm khác nhau so với lúc trình duyệt vẽ (paint) — và sự khác biệt thời điểm đó chính là điểm mấu chốt.
useEffect chạy sau khi trình duyệt đã vẽ. Nó bất đồng bộ và không chặn. Dùng cho gần như mọi thứ (dữ liệu, subscription, log).useLayoutEffect chạy đồng bộ sau khi DOM được sửa đổi nhưng TRƯỚC khi trình duyệt vẽ. Dùng khi bạn phải đọc layout và thay đổi DOM trong cùng một frame để tránh nhấp nháy nhìn thấy được.render → DOM cập nhật → [useLayoutEffect chạy] → trình duyệt vẽ → [useEffect chạy]
Hãy tưởng tượng đo một phần tử và định vị lại một tooltip dựa trên kích thước của nó. Với useEffect, người dùng sẽ thấy thoáng qua tooltip ở vị trí sai, rồi nó nhảy:
useLayoutEffect(() => {
const { height } = ref.current.getBoundingClientRect();
setTooltipTop(-height); // áp dụng TRƯỚC khi vẽ → không nhảy nhìn thấy
}, []);
Với useEffect, cùng code chạy sau khi vẽ → một frame nhấp nháy.
useLayoutEffect làm UI giật, vì trình duyệt không thể vẽ cho tới khi nó xong.Quy tắc ngón tay cái: mặc định dùng useEffect; chỉ dùng useLayoutEffect cho các phép đo/sửa đổi DOM đồng bộ mà nếu không sẽ nhấp nháy.
Thư viện câu hỏi phỏng vấn IT với đáp án chi tiết — từ Junior đến Senior.
Ủng hộ