useEffect vs useLayoutEffect: Khi Nào Dùng Cái Nào Cho Đúng?

Một trong những điểm dễ gây nhầm lẫn khi làm việc với React Hooks chính là sự tồn tại của hai hook có cú pháp gần như giống hệt nhau: useEffect và useLayoutEffect. Nếu không nắm vững nguyên lý hoạt động bên trong, bạn rất dễ chọn nhầm hook và vô tình gây ra hiện tượng giao diện bị giật (flickering) hoặc làm chậm toàn bộ ứng dụng. Bài viết này sẽ phân tích tường tận từng hook, giúp bạn luôn đưa ra quyết định chính xác trong mọi tình huống.

useEffectuseLayoutEffectReact hooksDOM
Ảnh bìa bài viết: useEffect vs useLayoutEffect: Khi Nào Dùng Cái Nào Cho Đúng?
Ảnh đại diện của Trung Vũ Hoàng

Trung Vũ Hoàng

Tác giả

22/3/20265 phút đọc

1. Side Effects Trong React Là Gì?

Trước khi đi vào so sánh, hãy làm rõ khái niệm Side Effects. Đây là những tác vụ xảy ra bên ngoài luồng render của React, chẳng hạn như: gọi API lấy dữ liệu, thao tác trực tiếp lên DOM, hay thiết lập subscription cho các sự kiện bên ngoài.

Cả useEffect lẫn useLayoutEffect đều phục vụ mục đích xử lý những tác vụ này — sự khác biệt cốt lõi nằm ở thời điểm chúng thực thi tương quan với chu kỳ vẽ (paint) của trình duyệt.

2. Cơ Chế Hoạt Động: Bất Đồng Bộ vs Đồng Bộ

useEffect — Hook "Thân Thiện Với Hiệu Năng"

useEffect là lựa chọn mặc định và phù hợp cho đại đa số trường hợp. Chuỗi thực thi diễn ra như sau:

  1. React nhận thấy State thay đổi.

  2. React tiến hành render lại Component.

  3. Trình duyệt vẽ (paint) giao diện mới ra màn hình.

  4. useEffect mới bắt đầu chạy.

Vì callback chỉ được gọi sau khi màn hình đã hoàn tất cập nhật, useEffect không hề cản trở trình duyệt — giúp giao diện phản hồi nhanh và mượt mà với người dùng.

useLayoutEffect — Hook "Ưu Tiên Độ Chính Xác Thị Giác"

Ngược lại, useLayoutEffect chen vào trước bước vẽ của trình duyệt:

  1. React nhận thấy State thay đổi.

  2. React render lại Component.

  3. useLayoutEffect thực thi ngay lập tức (đồng bộ).

  4. Trình duyệt mới được phép vẽ giao diện.

Điều này có nghĩa là mọi thay đổi bạn thực hiện bên trong useLayoutEffect đều được áp dụng trước khi người dùng kịp nhìn thấy bất kỳ kết quả render nào.

3. So Sánh Chi Tiết Các Đặc Điểm

Dưới đây là những tiêu chí quan trọng nhất để phân biệt hai hook này:

Thời điểm thực thi

  • useEffect: Chạy sau khi trình duyệt đã hiển thị giao diện (After Paint).

  • useLayoutEffect: Chạy trước khi trình duyệt hiển thị giao diện (Before Paint).

Kiểu thực thi

  • useEffect: Bất đồng bộ (Async) — không chặn luồng render.

  • useLayoutEffect: Đồng bộ (Sync) — chặn render cho đến khi hoàn thành.

Tác động lên hiệu năng

  • useEffect: Thân thiện với tốc độ tải trang, không gây gián đoạn.

  • useLayoutEffect: Dễ khiến trang bị "đứng" nếu xử lý tác vụ nặng bên trong.

Trường hợp sử dụng điển hình

  • useEffect: Gọi API, Analytics, Event Listener — bất kỳ thứ gì không cần thấy trước khi paint.

  • useLayoutEffect: Đo kích thước DOM, điều chỉnh vị trí phần tử — những thứ người dùng cần thấy đúng ngay từ khung hình đầu tiên.

4. Khi Nào Thực Sự Cần useLayoutEffect?

Dù React chính thức khuyến nghị ưu tiên useEffect, vẫn tồn tại những tình huống mà useLayoutEffect là giải pháp duy nhất để tránh trải nghiệm người dùng kém.

Tình Huống 1: Ngăn Giao Diện Bị Nháy (Flickering)

Giả sử bạn cần tính toán vị trí chính xác của một Tooltip dựa trên kích thước thực tế của nút bấm:

  • Với useEffect: Tooltip xuất hiện ở vị trí cũ → Trình duyệt vẽ → useEffect tính lại → Re-render → Tooltip "nhảy" sang chỗ mới. Người dùng thấy hiệu ứng giật rõ ràng.

  • Với useLayoutEffect: Vị trí được tính toán xong trước khi trình duyệt vẽ. Tooltip xuất hiện đúng chỗ ngay từ đầu, người dùng không nhận thấy bất kỳ sự giật nào.

Tình Huống 2: Đo Đạc Kích Thước DOM

Khi dùng getBoundingClientRect() hay các API đo lường DOM khác để xây dựng layout phức tạp, useLayoutEffect đảm bảo các giá trị thu được là chính xác — phản ánh trạng thái DOM thực tế — trước khi người dùng nhìn thấy kết quả cuối cùng.

5. Phân Tích Thứ Tự Thực Thi

Hãy xem đoạn code minh họa sau để thấy rõ thứ tự ưu tiên:

useLayoutEffect(() => {
  console.log("1. useLayoutEffect chạy");
}, [count]);

useEffect(() => {
  console.log("2. useEffect chạy");
}, [count]);

Mỗi khi count thay đổi, console luôn in 1 trước rồi mới đến 2 — bất kể thứ tự bạn khai báo trong component. Sự ưu tiên này là cố định và được React đảm bảo.

6. Nguyên Tắc Vàng Khi Chọn Hook

Đúc kết từ thực tế phát triển sản phẩm: Luôn bắt đầu với useEffect. Chỉ chuyển sang useLayoutEffect khi bạn quan sát thấy giao diện bị nháy hoặc sai lệch thị giác.

Lạm dụng useLayoutEffect sẽ vô hiệu hóa các cơ chế tối ưu render của React Concurrent Mode, khiến ứng dụng không thể tận dụng khả năng phân chia và ưu tiên hóa render theo từng khung hình.

Lưu ý với Next.js và SSR: Khi làm việc với Server-Side Rendering, tránh dùng useLayoutEffect ở cấp top-level component vì server không có DOM — điều này sẽ tạo ra cảnh báo trong quá trình build và có thể gây lỗi hydration.

7. Tổng Kết

Nắm vững sự khác biệt giữa useEffect vs useLayoutEffect là dấu hiệu của một lập trình viên React chín chắn. Quy tắc đơn giản để nhớ:

  • useEffect → Ưu tiên hiệu năng, chạy sau paint.

  • useLayoutEffect → Ưu tiên chính xác thị giác, chạy trước paint.

Hiểu rõ điểm này không chỉ giúp bạn trả lời tốt câu hỏi phỏng vấn mà còn xây dựng được những ứng dụng React có chất lượng thực sự cao.

Bạn thấy bài viết hữu ích?

Liên hệ với chúng tôi để được tư vấn miễn phí về dịch vụ

Liên hệ ngay

Bài viết liên quan

Ảnh bìa bài viết: Closure Trong JavaScript: Hiểu Tường Tận Để Lập Trình Như Chuyên Gia
Frontend

Closure Trong JavaScript: Hiểu Tường Tận Để Lập Trình Như Chuyên Gia

Closure — hay còn gọi là "hàm đóng" — là một trong những khái niệm quyền năng và cũng dễ gây bối rối nhất trong JavaScript. Nắm vững Closure không chỉ giúp bạn vượt qua phỏng vấn kỹ thuật cấp Senior mà còn thay đổi cách bạn kiến trúc toàn bộ codebase: gọn hơn, an toàn hơn, và ít bug hơn. Nhiều người hay nhầm lẫn giữa Scope và Closure, nhưng thực ra chúng có quan hệ chặt chẽ và bổ trợ cho nhau. Hãy cùng khám phá từ nền tảng.

29/3/2026
Ảnh bìa bài viết: useEffect vs useMemo: 5 Khác Biệt Quan Trọng Bạn Cần Hiểu Rõ
Frontend

useEffect vs useMemo: 5 Khác Biệt Quan Trọng Bạn Cần Hiểu Rõ

Nhầm lẫn giữa useEffect và useMemo là một trong những nguồn gốc phổ biến nhất gây ra các vấn đề hiệu suất trong ứng dụng React. Để dễ hình dung: hãy coi useMemo như một chiếc máy tính bỏ túi biết ghi nhớ kết quả, còn useEffect như một nhân viên trực tổng đài — chờ tín hiệu từ bên ngoài rồi mới hành động.

28/3/2026
Ảnh bìa bài viết: useMemo vs useCallback: 3 Bí Thuật Tối Ưu React Mà Senior Dev Áp Dụng
Frontend

useMemo vs useCallback: 3 Bí Thuật Tối Ưu React Mà Senior Dev Áp Dụng

Tối ưu hóa hiệu năng trong React thường bị coi là "vùng đất dữ" — nơi nhiều lập trình viên mắc kẹt với những quyết định sai lầm. Việc dùng useMemo và useCallback bừa bãi với hy vọng ứng dụng nhanh hơn đôi khi lại phản tác dụng, bắt CPU phải làm thêm việc so sánh dependencies không cần thiết. Bài viết này giúp bạn dùng hai hook này như một chuyên gia.

28/3/2026