Rewrite Zustand to be more simple and easier to use.
zustand.js
// Phiên bản đơn giản của Zustand
import React from "react";
// Hàm tạo store với các tính năng cốt lõi
function createStore(createState) {
// Lưu trữ state hiện tại
let state;
// Danh sách các hàm nghe (listener) để cập nhật khi state thay đổi
const listeners = new Set();
// Hàm để đăng ký các listener
const subscribe = (listener) => {
listeners.add(listener);
// Trả về hàm hủy đăng ký
return () => listeners.delete(listener);
};
// Hàm để cập nhật state
const setState = (partial) => {
// Tính toán state mới
const nextState = typeof partial === "function" ? partial(state) : partial;
// Kiểm tra nếu state thực sự thay đổi
if (nextState !== state) {
state = { ...state, ...nextState };
// Thông báo cho tất cả các listener
listeners.forEach((listener) => listener(state));
}
};
// Hàm để lấy state hiện tại
const getState = () => state;
// Khởi tạo state ban đầu
state = createState(setState, getState);
// Trả về các phương thức để làm việc với store
return {
getState,
setState,
subscribe,
};
}
// Hàm tạo hook để sử dụng trong React
function createHook(store) {
return function useStore(selector) {
// React hook để quản lý state
const [state, setState] = React.useState(
selector ? selector(store.getState()) : store.getState()
);
// Effect để đăng ký và hủy đăng ký listener
React.useEffect(() => {
const handleChange = (newState) => {
const selectedState = selector ? selector(newState) : newState;
// Chỉ cập nhật nếu state thay đổi
setState(selectedState);
};
// Đăng ký listener
const unsubscribe = store.subscribe(handleChange);
// Hủy đăng ký khi component unmount
return unsubscribe;
}, [selector]);
return state;
};
}
// Hàm chính để tạo store dễ dàng
function create(createState) {
// Tạo store
const store = createStore(createState);
// Tạo hook để sử dụng store
const useStore = createHook(store);
// Trả về hook và một số phương thức bổ sung
return Object.assign(useStore, {
getState: store.getState,
setState: store.setState,
subscribe: store.subscribe,
});
}
export { create, createHook, createStore };
// Giải thích nguyên lý hoạt động:
// 1. createStore: Tạo cơ chế quản lý state cơ bản
// - Lưu trữ state
// - Cho phép đăng ký các listener
// - Cung cấp phương thức cập nhật state
// 2. createHook: Tạo hook React để sử dụng store
// - Quản lý state local
// - Đăng ký listener để theo dõi thay đổi
// - Chỉ render lại khi state thay đổi
// 3. create: Hàm chính để tạo store dễ dàng
// - Kết hợp createStore và createHook
// - Cung cấp API đơn giản để tạo và sử dụng store
// Các nguyên tắc chính:
// - Immutability: Luôn tạo state mới thay vì mutate
// - Minimal API: Chỉ cung cấp các phương thức cần thiết
// - Hiệu năng: Chỉ render khi state thực sự thay đổi
// Ý tưởng chính của thư viện:
// Zustand giải quyết các vấn đề quản lý state trong React bằng cách:
// - Tạo một store trung tâm để lưu trữ state
// - Cung cấp cơ chế đăng ký và theo dõi thay đổi
// - Cho phép cập nhật state một cách dễ dàng và hiệu quả
// - Giảm thiểu việc truyền props qua nhiều tầng component
App.js
import React from "react";
import { create } from "./zustand";
// Sử dụng hàm create đã định nghĩa từ đoạn code trước
// Tạo store quản lý trạng thái người dùng
const useUserStore = create((set) => ({
// Trạng thái ban đầu
user: null,
isLoggedIn: false,
theme: "light",
// Các action để thay đổi state
login: (userData) =>
set({
user: userData,
isLoggedIn: true,
}),
logout: () =>
set({
user: null,
isLoggedIn: false,
}),
toggleTheme: () =>
set((state) => ({
theme: state.theme === "light" ? "dark" : "light",
})),
}));
// Component Profile sử dụng store
const Profile = () => {
// Truy xuất state và actions từ store
const { user, isLoggedIn, login, logout } = useUserStore();
return (
<div className={`p-6 ${isLoggedIn ? "bg-green-100" : "bg-red-100"}`}>
{isLoggedIn ? (
<div>
<h2 className="text-2xl">Xin chào, {user.name}</h2>
<p>Email: {user.email}</p>
<button onClick={()=> logout()} className="mt-4 bg-red-500 text-white p-2 rounded">
Đăng xuất
</button>
</div>
) : (
<button
onClick={()=>
login({
name: "Nguyễn Văn A",
email: "[email protected]",
})
}
className="bg-blue-500 text-white p-2 rounded"
>
Đăng nhập
</button>
)}
</div>
);
};
// Component chính
const UserManagementApp = () => {
return (
<div className="max-w-md mx-auto mt-10 space-y-4">
<h1 className="text-3xl font-bold text-center">Quản Lý Người Dùng</h1>
<Profile />
<StateLogger /> {/* Component để hiển thị toàn bộ state */}
</div>
);
};
// Component để in ra toàn bộ state (để minh họa)
const StateLogger = () => {
// Lấy toàn bộ state
const state = useUserStore();
return (
<div className="bg-gray-100 p-4 rounded">
<h3 className="font-bold mb-2">Trạng Thái Hiện Tại:</h3>
<pre>{JSON.stringify(state, null, 2)}</pre>
</div>
);
};
export default UserManagementApp;
// Giải thích chi tiết về ví dụ:
// 1. Tạo store với nhiều trạng thái và actions
// 2. Sử dụng selector để lấy một phần state
// 3. Các component khác nhau có thể truy cập và thay đổi state
// 4. Không cần truyền props hay sử dụng Context
// 5. Dễ dàng mở rộng và quản lý state toàn cục