Quản lý state với Context API hoặc Zustand

Tạo bởi Hoàng Vũ, chỉnh sửa cuối lúc 11 tháng 4, 2025

Trong các ứng dụng React/Next.js thực tế, việc chia sẻ dữ liệu giữa nhiều component là rất phổ biến, đặc biệt với các ứng dụng như CRUD, xác thực người dùng, giỏ hàng, theme… Trong bài này, học viên sẽ được giới thiệu hai phương pháp phổ biến để quản lý state toàn cục trong Next.js: Context APIZustand.

Quản lý state với Context API hoặc Zustand

1. Quản lý state với Context API

Context API là công cụ sẵn có trong React, dùng để chia sẻ dữ liệu giữa các component mà không cần truyền props thủ công qua nhiều tầng.

a. Tạo context

// context/TodoContext.js
import { createContext, useState, useContext } from 'react'

const TodoContext = createContext()

export function TodoProvider({ children }) {
  const [todos, setTodos] = useState([])

  const addTodo = (title) => {
    const newTodo = { id: Date.now(), title, done: false }
    setTodos([...todos, newTodo])
  }

  const removeTodo = (id) => {
    setTodos(todos.filter(todo => todo.id !== id))
  }

  return (
    <TodoContext.Provider value={{ todos, addTodo, removeTodo }}>
      {children}
    </TodoContext.Provider>
  )
}

export const useTodo = () => useContext(TodoContext)

b. Bọc context trong _app.js

import { TodoProvider } from '@/context/TodoContext'

export default function App({ Component, pageProps }) {
  return (
    <TodoProvider>
      <Component {...pageProps} />
    </TodoProvider>
  )
}

c. Dùng context trong component

import { useTodo } from '@/context/TodoContext'

export default function TodoList() {
  const { todos, removeTodo } = useTodo()

  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>
          {todo.title}
          <button onClick={() => removeTodo(todo.id)}>Xoá</button>
        </li>
      ))}
    </ul>
  )
}
  • Ưu điểm: Sẵn có trong React, không cần thư viện ngoài.
  • Nhược điểm: Không tối ưu hiệu năng nếu không chia nhỏ context, dễ render lại toàn bộ.

2. Quản lý state với Zustand

Zustand là một thư viện quản lý state siêu nhẹ, nhanh, đơn giản hơn Redux nhiều lần, phù hợp với cả ứng dụng nhỏ và lớn.

a. Cài đặt Zustand

npm install zustand

b. Tạo store

// store/todoStore.js
import { create } from 'zustand'

export const useTodoStore = create((set) => ({
  todos: [],
  addTodo: (title) =>
    set((state) => ({
      todos: [...state.todos, { id: Date.now(), title, done: false }]
    })),
  removeTodo: (id) =>
    set((state) => ({
      todos: state.todos.filter(todo => todo.id !== id)
    }))
}))

c. Sử dụng store

import { useTodoStore } from '@/store/todoStore'

export default function TodoList() {
  const todos = useTodoStore(state => state.todos)
  const removeTodo = useTodoStore(state => state.removeTodo)

  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>
          {todo.title}
          <button onClick={() => removeTodo(todo.id)}>Xoá</button>
        </li>
      ))}
    </ul>
  )
}
  • Ưu điểm: Nhẹ, đơn giản, dễ chia nhỏ store, dễ dùng hơn Redux
  • Nhược điểm: Cần cài thêm thư viện (nhưng rất nhỏ)

3. So sánh Context API và Zustand

Tiêu chí Context API Zustand
Cài đặt thêm Không Cần (npm install)
Cách dùng Trung bình Rất dễ
Hiệu năng Render lại nhiều Hiệu năng cao
Quy mô dự án Nhỏ, đơn giản Mọi loại dự án
Đa store / modular Khó chia nhỏ Dễ chia nhiều store

4. Áp dụng trong dự án thực tế

CRUD Todo:

  • Dùng Zustand để quản lý danh sách todo.
  • Thay vì gọi API mỗi lần, thao tác trực tiếp lên store local (mock).
  • Kết hợp fetch và store để sync dữ liệu từ server về client.

Xác thực người dùng:

  • Context thường dùng để lưu user session, trạng thái đăng nhập (vì thường cần cập nhật toàn bộ layout).
  • Zustand có thể dùng nếu muốn quản lý nhiều logic liên quan đến user (vai trò, quyền hạn, setting cá nhân...).

Kết luận

Sau bài học này, học viên đã nắm được:

  • Cách dùng Context API để chia sẻ state trong toàn ứng dụng
  • Cách tạo và dùng Zustand store đơn giản, hiệu quả
  • So sánh giữa hai phương pháp quản lý state
  • Ứng dụng chúng vào các dự án CRUD hoặc xác thực người dùng

Context API phù hợp cho state "global nhưng ít thay đổi", còn Zustand nên dùng cho các state thường xuyên thay đổi, cần hiệu năng cao.

Website Logo

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.

Bình luận

Website Logo

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.

Liên hệ công việc qua email dưới đây.

lhvuctu@gmail.com

Chúng Tôi Trên

Bạn đang muốn học về lập trình website?

Bạn cần nâng cao kiến thức chuyên nghiệp hơn để nâng cao cơ hội nghề nghiệp? Liên hệ