Trong mô hình Monorepo E-commerce này, chúng ta phân chia State thành 2 loại rõ rệt.
1. Server State (Async Data) -> React Query
Dữ liệu từ Server (Danh sách sản phẩm, Chi tiết đơn hàng) KHÔNG nên lưu trong Redux/Zustand. Chúng nên được quản lý bởi TanStack Query (hoặc SWR).
Lợi ích:
- Tự động Caching & Deduping.
- Tự động Re-fetch khi focus cửa sổ.
- Xử lý Loading/Error states cực nhàn.
tsx:
// apps/merchant/hooks/use-orders.ts
import { useQuery } from "@tanstack/react-query";
import { getOrders } from "@/actions/order";
export function useOrders(page: number) {
return useQuery({
queryKey: ['orders', page],
queryFn: () => getOrders(page),
staleTime: 5 * 60 * 1000, // 5 phút chưa cần fetch lại
});
}2. Client State (UI State) -> Zustand
Dữ liệu thuần Client (Giỏ hàng, Sidebar Toggle, Modal Open/Close) được quản lý bởi Zustand.
Tại sao Zustand?
- Nhẹ hơn Redux (dưới 1KB).
- API đơn giản (Hooks base).
- Không cần bọc Context Provider.
tsx:
// apps/store/store/cart.ts
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface CartState {
items: CartItem[];
addItem: (product: Product) => void;
removeItem: (id: string) => void;
}
export const useCartStore = create<CartState>()(
persist(
(set) => ({
items: [],
addItem: (product) => set((state) => {
// Logic thêm vào giỏ...
}),
removeItem: (id) => set((state) => ({
items: state.items.filter(i => i.id !== id)
})),
}),
{ name: 'shopping-cart' } // Tự động lưu vào LocalStorage
)
);3. URL State (The Truth)
Với Admin Dashboard (Filter, Search, Pagination), trạng thái PHẢI nằm trên URL.
- User có thể copy link gửi cho sếp -> Sếp thấy đúng trạng thái đó.
- Refresh trang không bị mất filter.
Bad:
tsx:
const [search, setSearch] = useState("");Good:
tsx:
const searchParams = useSearchParams();
const search = searchParams.get("search");
const handleSearch = (term) => {
router.push(`?search=${term}`);
}Tổng kết
| Loại State | Công nghệ | Áp dụng cho |
|---|---|---|
| Server State | React Query | API Respsonse, DB Data |
| Client Global | Zustand | Cart, Theme, User Session (Client side) |
| URL State | Next.js Router | Search, Sort, Pagination, filter |
| Form State | React Hook Form | Form validation, Input values |