Bài 5: Context API – Quản lý trạng thái toàn cục

Trong các bài trước, chúng ta đã truyền dữ liệu từ Component Cha xuống Component Con bằng Props. Nhưng nếu ứng dụng của bạn có 5-10 tầng component lồng nhau, việc phải truyền đi truyền lại một biến qua tất cả các tầng (còn gọi là Prop Drilling) sẽ khiến code cực kỳ rối rắm và khó bảo trì.
Context API ra đời để giúp bạn “nhảy cóc” – truyền thẳng dữ liệu đến bất kỳ component nào cần, bất kể nó nằm sâu bao nhiêu tầng.
Context là gì?
Hãy tưởng tượng dữ liệu như một món hàng Sốp pi. Với Props, gói hàng phải qua tay hàng chục bước trung gian và shipper mới đến được tay người dùng (Component). Còn với Context, shop chỉ cần gửi thẳng hàng đến “kho lưu trữ chung” (tủ nhận hàng), ai cần thì đến đó lấy. Như vậy hàng hóa vẫn đến tay người dùng, nhờ giảm được các công đoạn truyền tải trung gian cồng kềnh, thời gian nhận hàng nhanh hơn rất nhiều và tiết kiệm chi phí vận chuyển.
Quay lại với Context, nó giúp bạn quản lý trạng thái toàn cục (global state) mà không làm ảnh hưởng đến bộ truyền tham số của các component trung gian.
Cách thiết lập Context (3 bước)
Bước 1: Tạo Context (Kho chứa trạng thái toàn cục)
Tạo file ThemeContext.jsx để lưu trữ dữ liệu cần chia sẻ:
import { createContext } from 'react'; // Tạo một Context với giá trị mặc định là 'light' export const ThemeContext = createContext<string>('light');
Bước 2: Bọc Provider (Cung cấp dữ liệu)
Tại component cha cao nhất (thường là App.tsx), hãy bao bọc các component con bằng Provider:
import { ThemeContext } from './ThemeContext';
function App() {
return (
<ThemeContext.Provider value="dark">
<MainPage />
</ThemeContext.Provider>
);
}
Bước 3: Lấy dữ liệu (Consumer)
Tại bất kỳ component con nào (dù nằm sâu bao nhiêu tầng), bạn chỉ cần dùng hook useContext:
import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';
function CurrentTheme() {
const theme = useContext(ThemeContext);
return <p>Giao diện hiện tại: {theme}</p>;
}
Ưu và nhược điểm
Để sử dụng Context API một cách hiệu quả, bạn cần nắm rõ hai mặt của nó:
✅ Ưu điểm
- Loại bỏ Prop Drilling: Giải quyết triệt để việc truyền dữ liệu qua nhiều tầng component trung gian không cần thiết.
- Quản lý trạng thái toàn cục: Cực kỳ hữu ích cho các trạng thái cần truy cập ở khắp mọi nơi trong ứng dụng như: Theme (Dark/Light mode), Thông tin người dùng (User Auth), Ngôn ngữ (i18n).
- Code sạch và dễ đọc: Component chỉ cần nhận dữ liệu từ “nơi cần lấy”, không cần bận tâm về cấu trúc phân cấp phức tạp.
⚠️ Nhược điểm
- Vấn đề Re-render (Hiệu năng): Khi giá trị của
Providerthay đổi, tất cả các component tiêu thụ (useContext) sẽ tự động re-render lại. Nếu Context chứa dữ liệu thay đổi quá thường xuyên (như dữ liệu realtime mỗi miligiây), ứng dụng có thể bị giật lag. - Khó tái sử dụng (Coupling): Component sử dụng Context sẽ bị phụ thuộc vào cái Context đó. Bạn không thể dễ dàng mang component đó sang một dự án khác nếu không có Context tương ứng đi kèm.
- Không thay thế được Redux/Zustand: Với các ứng dụng phức tạp cần quản lý hàng loạt state tương tác qua lại, Context API không có các tính năng tối ưu hóa như
selectorshaymiddlewarenhư các thư viện quản lý trạng thái chuyên dụng.
Khi nào nên dùng Context?
Context API là một công cụ mạnh mẽ, nhưng giống như bất kỳ vũ khí nào, nếu dùng sai cách nó sẽ trở thành “gánh nặng” cho ứng dụng. Tóm lại, quy tắc vàng để bạn sử dụng Context hiệu quả:
- Nên dùng: Khi bạn cần chia sẻ dữ liệu mà nhiều component ở các tầng khác nhau đều cần dùng đến, cần code sạch và dễ quản lý trạng thái toàn cục.
- Không nên dùng: Khi dữ liệu thay đổi quá thường xuyên, component cần tái sử dụng và xử lý các logic phức tạp.
Lời kết
Giờ đây bạn đã có trong tay bộ công cụ quản lý dữ liệu chuyên nghiệp từ cục bộ (useState) đến toàn cục (Context API). Chúng ta đã sẵn sàng để lắp ghép tất cả lại.
Ở bài sau, tất cả kiến thức từ bài 1 -> 5 sẽ được tổng hợp trong một dự án nhỏ thực tế. Chúng ta sẽ cùng xây dựng một ứng dụng Todo List hoàn chỉnh: thêm, xóa, sửa và quản lý danh sách việc cần làm. Đừng bỏ lỡ Bài 6: Thực hành tổng hợp – Xây dựng Todo List App nhé!





