Zustand vs Jotai vs Signals: State management 2026
So sánh thực tế 3 thư viện state management phổ biến nhất 2026 — Zustand, Jotai và Signals. Khi nào dùng cái nào?
Redux đã là quá khứ với phần lớn dự án React mới. Năm 2026, cuộc chơi state management xoay quanh 3 cái tên: Zustand, Jotai, và Signals (qua @preact/signals-react hoặc TC39 proposal). Mình đã dùng cả 3 trong production — đây là so sánh thực tế.
Zustand — Store-based, đơn giản
Zustand theo mô hình single store giống Redux, nhưng API minimal đến bất ngờ. Không cần provider, không boilerplate:
import { create } from "zustand";
import { devtools, persist } from "zustand/middleware";
interface CartStore {
items: CartItem[];
addItem: (item: CartItem) => void;
removeItem: (id: string) => void;
total: () => number;
}
export const useCartStore = create<CartStore>()(
devtools(
persist(
(set, get) => ({
items: [],
addItem: (item) =>
set((state) => ({ items: [...state.items, item] })),
removeItem: (id) =>
set((state) => ({
items: state.items.filter((i) => i.id !== id),
})),
total: () =>
get().items.reduce((sum, i) => sum + i.price * i.qty, 0),
}),
{ name: "cart-storage" }
)
)
);
Ưu điểm: API nhỏ gọn, middleware ecosystem tốt (persist, devtools, immer), TypeScript support tuyệt vời. Phù hợp khi bạn cần global store với logic tập trung.
Nhược điểm: Selector pattern có thể gây re-render nếu không cẩn thận. Cần dùng shallow compare hoặc tách slice.
Jotai — Atomic state
Jotai theo triết lý atomic — mỗi piece of state là một atom độc lập. Lấy cảm hứng từ Recoil nhưng API đơn giản hơn nhiều:
import { atom, useAtom } from "jotai";
import { atomWithStorage } from "jotai/utils";
// Primitive atoms
const themeAtom = atomWithStorage("theme", "light");
const fontSizeAtom = atom(16);
// Derived atom — tự động update khi dependencies thay đổi
const cssVarsAtom = atom((get) => ({
"--font-size": `${get(fontSizeAtom)}px`,
"--bg-color": get(themeAtom) === "dark" ? "#1a1a1a" : "#ffffff",
}));
// Async atom — fetch data
const userAtom = atom(async () => {
const res = await fetch("/api/me");
return res.json();
});
Ưu điểm: Granular re-renders (chỉ component dùng atom đó mới update), composable, async atoms built-in, không cần provider (v2+).
Nhược điểm: Với app lớn, quản lý hàng trăm atoms có thể khó track. Thiếu built-in devtools mạnh như Zustand.
Signals — Reactive primitives
Signals đang là trend lớn nhất. TC39 đã đưa vào Stage 1 proposal. Trong React ecosystem, @preact/signals-react là implementation phổ biến nhất. Signals bypass React's rendering — update DOM trực tiếp mà không trigger re-render.
Ưu điểm: Performance cực tốt, fine-grained reactivity, API đơn giản. Tương lai của web frameworks.
Nhược điểm: Trong React, signals vẫn là "hack" — đi ngược lại React's mental model. Có thể conflict với React Compiler. Chưa ổn định cho production lớn.
Khi nào dùng cái nào?
Zustand — App cần global store rõ ràng: e-commerce cart, complex form wizard, multi-step workflows. Team đông, cần conventions.
Jotai — App có nhiều independent state pieces: settings panels, feature flags, UI preferences. Khi cần granular re-render control.
Signals — Performance-critical UI: real-time dashboards, animation-heavy apps. Nhưng hãy cẩn thận với React compatibility.
Kết luận
Không có winner tuyệt đối. Zustand cho simplicity + conventions, Jotai cho flexibility + granularity, Signals cho raw performance. Cá nhân mình default Zustand cho hầu hết projects, chuyển sang Jotai khi cần atomic patterns. Signals thì chờ TC39 proposal mature thêm.
Admin
Bình luận (0)
Đăng nhập để bình luận
Chưa có bình luận nào. Hãy là người đầu tiên!