Tạm biệt Redux Boilerplate: Quản lý State React ‘nhẹ tênh’ với Zustand

Development tutorial - IT technology blog
Development tutorial - IT technology blog

Zustand: Chạy bộ thay vì vác tạ Redux

Bạn đã bao giờ thấy “kiệt sức” khi phải viết hàng chục dòng boilerplate chỉ để cập nhật một cái tên user trong Redux chưa? Nếu rồi, Zustand chính là giải pháp cứu cánh. Với triết lý tối giản, thư viện này chỉ nặng vỏn vẹn 1.1KB. Bạn không cần dùng Provider bao bọc app, cũng chẳng cần mớ hỗn độn actions.js hay reducers.js.

Cài đặt trong nháy mắt:

npm install zustand
# hoặc
yarn add zustand

Hãy thử tạo một store quản lý số đếm (Counter). Bạn sẽ thấy sự khác biệt ngay lập tức:

import { create } from 'zustand'

const useCounterStore = create((set) => ({
  count: 0,
  inc: () => set((state) => ({ count: state.count + 1 })),
  dec: () => set((state) => ({ count: state.count - 1 })),
}))

function Counter() {
  const { count, inc, dec } = useCounterStore()
  return (
    <div>
      <h1>{count}</h1>
      <button onClick={inc}>Tăng</button>
      <button onClick={dec}>Giảm</button>
    </div>
  )
}

Điểm cộng lớn nhất? Bạn chỉ cần import hook và dùng trực tiếp. Không cần cấu hình <Provider> rắc rối ở file root.

Tại sao dự án thực tế nên chọn Zustand?

Trong một dự án Dashboard phức tạp mình từng tham gia, việc dùng Context API khiến hiệu năng bị nghẽn cổ chai. Mỗi lần user gõ phím vào input, cả tá biểu đồ phía dưới bị re-render vô tội vạ. Khi chuyển sang Zustand, tốc độ phản hồi của UI tăng khoảng 30% nhờ cơ chế render thông minh.

Zustand giải quyết triệt để 3 vấn đề lớn:

  • Kiểm soát Render: Chỉ component nào thực sự dùng dữ liệu thay đổi mới bị render lại.
  • API hiện đại: Tận dụng triệt để sức mạnh của React Hooks, cực kỳ thân thiện với dev.
  • Truy cập linh hoạt: Bạn có thể lấy state ngay trong file cấu hình API hoặc utils mà không cần hook.

Những tính năng then chốt trong thực chiến

1. Xử lý Async Actions đơn giản đến bất ngờ

Quên middleware như Redux-Thunk đi. Với Zustand, bạn chỉ việc dùng async/await ngay trong store như một hàm JavaScript bình thường.

const useUserStore = create((set) => ({
  users: [],
  loading: false,
  fetchUsers: async () => {
    set({ loading: true })
    try {
      const res = await fetch('https://api.example.com/users')
      const data = await res.json()
      set({ users: data, loading: false })
    } catch (error) {
      set({ loading: false })
      console.error("Lỗi tải dữ liệu:", error)
    }
  },
}))

2. Persist Middleware – Lưu state tự động

Tính năng lưu giỏ hàng hoặc theme vào localStorage thường tốn khá nhiều code logic. Zustand xử lý việc này chỉ với một hàm bọc duy nhất.

import { persist } from 'zustand/middleware'

const useSettingsStore = create(
  persist(
    (set) => ({
      theme: 'dark',
      toggleTheme: () => set((s) => ({ theme: s.theme === 'dark' ? 'light' : 'dark' })),
    }),
    { name: 'user-preferences' }
  )
)

Tối ưu hiệu năng: Đừng lấy cả “cửa hàng” ra dùng

Nhiều bạn mới thường mắc lỗi const state = useStore(). Điều này khiến component render lại mỗi khi bất kỳ giá trị nào trong store thay đổi. Hãy sử dụng Selector để tối ưu:

// Chỉ render lại khi count thay đổi
const count = useCounterStore((state) => state.count)
const inc = useCounterStore((state) => state.inc)

Cách tiếp cận này giúp ứng dụng của bạn mượt mà hơn, đặc biệt là khi store phình to.

Kinh nghiệm tổ chức Store khi dự án lớn dần

Áp dụng Slices Pattern

Đừng dồn tất cả logic vào một file duy nhất. Hãy chia nhỏ store thành các “Slice” riêng biệt (ví dụ: AuthSlice, CartSlice) rồi gộp chúng lại. Cách này giúp code dễ đọc, dễ bảo trì và dễ viết Unit Test hơn.

Sử dụng Redux DevTools

Zustand tích hợp cực tốt với Redux DevTools. Bạn vẫn có thể debug, xem lịch sử thay đổi state y hệt như đang dùng Redux, nhưng với một setup đơn giản hơn nhiều.

Biết khi nào không nên dùng Store

Đừng lạm dụng. Nếu một trạng thái chỉ phục vụ duy nhất một component (như trạng thái đóng/mở của một modal lẻ), useState của React vẫn là lựa chọn tốt nhất. Hãy chỉ đưa lên Store những dữ liệu cần chia sẻ giữa nhiều màn hình hoặc cần lưu trữ lâu dài.

Lời kết

Zustand không chỉ là một công viện, nó là một tư duy quản lý state thực dụng. Nó ưu tiên tốc độ dev và hiệu năng thực tế thay vì những quy chuẩn rườm rà. Nếu bạn đang khởi tạo một project React mới, hãy thử dùng Zustand. Chắc chắn bạn sẽ không hối hận vì sự lựa chọn này.

Chúc bạn có những trải nghiệm code thật sướng!

Share: