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.

useEffectuseMemoso sánhkhác biệthook Reactside effect
Ả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õ
Ảnh đại diện của Trung Vũ Hoàng

Trung Vũ Hoàng

Tác giả

28/3/20264 phút đọc

1. Bản Chất Cốt Lõi Của Từng Hook

useMemo được sinh ra để giải quyết bài toán Memoization — lưu giữ kết quả của một phép tính tốn kém và chỉ tính toán lại khi các dependency thực sự thay đổi. Mục tiêu duy nhất của nó là ngăn các phép tính nặng chạy lại vô ích sau mỗi lần Component re-render.

useEffect thì ngược lại — đây là nơi xử lý Side Effects: những tác vụ nằm ngoài phạm vi hiển thị của Component như gọi API, thiết lập subscription, hay tương tác trực tiếp với DOM. Nếu bạn nhét logic tính toán vào useEffect, React buộc phải render thêm một lần nữa để cập nhật trạng thái — lãng phí hoàn toàn.

2. Thời Điểm Thực Thi: Khác Biệt Sống Còn

useMemo chạy ngay trong quá trình render (Rendering phase). Khi React đọc code Component để chuẩn bị xuất UI, nó kiểm tra dependency array của useMemo — nếu không thay đổi, giá trị cũ được trả về ngay lập tức. Vì vậy, tuyệt đối không được đưa side effect vào bên trong useMemo, điều đó sẽ làm chậm quá trình hiển thị.

useEffect chỉ chạy sau khi render hoàn tất và trình duyệt đã vẽ xong UI (Commit phase). Thiết kế này đảm bảo các tác vụ nặng như fetch data không block người dùng nhìn thấy giao diện — đây là chủ tâm của React để giữ ứng dụng luôn phản hồi nhanh.

3. Khi Nào Nên Dùng useMemo?

Chỉ nên dùng useMemo trong hai tình huống rõ ràng:

  • Phép tính nặng: Lọc danh sách hàng ngàn phần tử, chạy thuật toán tìm kiếm phức tạp, xử lý dữ liệu lớn...

  • Đảm bảo tính nhất quán tham chiếu: Khi bạn trả về Object hoặc Array và truyền xuống Component con wrapped bởi React.memo. Nếu không có useMemo, Object mới được tạo sau mỗi render — Component con coi đó là "dữ liệu mới" và re-render vô ích.

Đừng dùng useMemo cho phép tính đơn giản — chi phí khởi tạo hook và so sánh dependency có thể còn lớn hơn lợi ích mang lại.

4. Ứng Dụng Thực Tế Của useEffect

useEffect là trạm điều khiển cho mọi thứ diễn ra bên ngoài Component. Các tình huống phổ biến nhất:

  • Gọi API khi Component mount hoặc khi dependency thay đổi.

  • Đăng ký (subscribe) WebSocket để nhận dữ liệu thời gian thực.

  • Thiết lập và dọn dẹp Event Listener.

Một điểm mà useMemo hoàn toàn không có: hàm cleanup. Khi Component unmount hoặc trước khi effect chạy lại, hàm cleanup cho phép bạn hủy yêu cầu API đang dở, xóa listener, giải phóng bộ nhớ — tránh memory leak.

Mẹo nhỏ: Trước khi dùng useEffect để cập nhật state, hãy tự hỏi: "Có thể tính toán giá trị này trực tiếp trong render không?" Nếu có — hãy dùng useMemo hoặc tính thẳng trong thân hàm. Không cần useEffect.

5. Tổng Hợp 5 Khác Biệt Then Chốt

Khác biệt 1: Mục đích

  • useMemo → Ghi nhớ giá trị ("nhớ cái gì đó").

  • useEffect → Xử lý side effect ("làm gì đó").

Khác biệt 2: Thời điểm chạy

  • useMemo → Trong quá trình render (Before Paint).

  • useEffect → Sau khi render hoàn tất (After Paint).

Khác biệt 3: Giá trị trả về

  • useMemo → Một giá trị cụ thể (số, chuỗi, mảng, object...).

  • useEffect → undefined hoặc một hàm cleanup.

Khác biệt 4: Hỗ trợ cleanup

  • useMemo → Không có.

  • useEffect → Có hàm cleanup khi unmount hoặc dependency thay đổi.

Khác biệt 5: Ảnh hưởng đến render

  • useMemo → Tránh render thừa bằng cách giữ nguyên giá trị.

  • useEffect → Có thể kích hoạt thêm render nếu cập nhật state bên trong.

6. Những Sai Lầm Cần Tránh

Stale Closures: Dùng biến bên trong hook nhưng quên khai báo trong dependency array. Code đọc dữ liệu cũ mà không có bất kỳ cảnh báo nào — loại bug âm thầm khó tìm nhất.

Xử lý event trong useEffect: Khi người dùng click "Mua hàng", xử lý logic ngay trong onClick — đừng thay đổi state trung gian rồi chờ useEffect "bắt" lấy. Cách trực tiếp luôn rõ ràng và dễ debug hơn.

Một useEffect làm quá nhiều việc: Tuân thủ nguyên tắc Single Responsibility — mỗi useEffect chỉ đảm nhận một nhiệm vụ. Điều này giúp React quản lý re-render chính xác hơn và giúp đồng đội đọc code dễ hơn.

Tổng Kết

Điều tốt nhất bạn có thể làm là giữ Component đơn giản nhất có thể. Viết code đúng chức năng trước — rồi mới đo lường bằng công cụ profiler để quyết định có cần Memoize hay không. Đừng tối ưu hóa vội vàng dựa trên cảm tính.

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: 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
Ảnh bìa bài viết: useMemo vs useCallback: 5 Sai Lầm Khiến React App Của Bạn Chậm Đi
Frontend

useMemo vs useCallback: 5 Sai Lầm Khiến React App Của Bạn Chậm Đi

Hiểu đúng bản chất của Memoization là nền tảng để bạn tránh những lỗi sai cơ bản và xây dựng codebase sạch, dễ bảo trì hơn. Bài viết này phân tích kỹ lưỡng cách hai hook hoạt động, điểm khác nhau giữa chúng và — quan trọng hơn cả — những tình huống bạn tuyệt đối không nên dùng chúng.

22/3/2026