Chapter 8: When useState Falls Short - Zustand, the State Management Master

When your backend system only has one or two pages, the useState we learned in Chapter 1 is absolutely sufficient.
But as the system grows larger, you might encounter a major headache:

Imagine you call a punch-in API on the Dashboard page and obtain an array called punchRecords.
Then your "Chart" component needs this array to draw graphs, your "DataTable" component needs it to display the list, and your "Sidebar" needs it to calculate how many people were late today.

If you only use useState, you'll find yourself passing this punchRecords like a relay baton - from the top-level parent component, down through layers of props to all child components.
This phenomenon is known in the industry as "Prop Drilling". It turns your code into a tangled mess, and if any layer fails to pass it correctly, the whole system breaks!

To solve this problem, we need "Global State Management".

๐ŸŽฏ Chapter Goals

  1. Understand the concept of global state management: What is a Store?
  2. Get to know Zustand, the most recommended and lightweight state management library in the React community.
  3. Create a global userStore to manage logged-in user information.
  4. Learn how to read/write the same global data between two completely unrelated components.

๐Ÿป Why Choose Zustand Over the Veteran Redux?

If you look up React tutorials from five years ago, they would definitely teach you to use Redux.
While Redux is powerful, it requires dozens of lines of boilerplate code just to store a tiny variable, and it's filled with inhuman terms like Reducer, Dispatch, and Action.

Zustand (German for "state") is an adorable bear. Its philosophy is: "The simpler, the better."
It creates a "shared warehouse (Store)" in the cloud for you. Any component can directly access or modify data in the warehouse with the right key (Hook), without needing to pass through parent components!


๐Ÿ“ฆ Step 1: Let AI Help You Create the Store

๐Ÿ”ฅใ€Vibe Promptๅฎžๆˆ˜ๅ’’่ฏญใ€‘
I need to use Zustand for global state management in React (Vite).
1. Give me the npm installation command.
2. Help me create a userStore.ts in src/store/.
3. This store should include userInfo (an object with name, role, avatar fields, defaulting to null).
4. Provide two state update functions: setUserInfo (for writing data during login) and clearUser (for clearing data during logout).
5. Add TypeScript type definitions for editor autocompletion.

AI will instruct you to install via terminal:

npm install zustand

And generate this elegantly simple store configuration:

// ๐Ÿ“‚ src/store/userStore.ts
import { create } from 'zustand';

// 1. Define what's in the store (TypeScript types)
interface UserInfo {
  name: string;
  role: string;
  avatar?: string;
}

interface UserState {
  userInfo: UserInfo | null;
  setUserInfo: (user: UserInfo) => void;
  clearUser: () => void;
}

// 2. Create and expose this warehouse
export const useUserStore = create<UserState>((set) => ({
  userInfo: null, // Default: no one logged in
  
  // Magic for writing data: call set() to update the store
  setUserInfo: (user) => set({ userInfo: user }),
  
  // Magic for clearing data
  clearUser: () => set({ userInfo: null }),
}));

๐Ÿš€ Step 2: "Grab and Go" Anywhere

Now this warehouse floats above your website. You can access data from any corner!

Scenario A: Reading Name in Navbar (Navbar.tsx)

import { useUserStore } from '../store/userStore';

export default function Navbar() {
  // Simply call our Hook, specifying we only want userInfo
  const userInfo = useUserStore((state) => state.userInfo);
  
  return (
    <nav className="bg-white p-4 flex justify-between shadow-sm">
      <div className="font-bold">Punch-In System Admin</div>
      {/* Show different text based on login status */}
      <div className="text-blue-600">
        Hello, {userInfo ? userInfo.name : 'Guest'}
      </div>
    </nav>
  );
}

Scenario B: Writing Data in Login Page (Login.tsx)

import { useUserStore } from '../store/userStore';

export default function Login() {
  // This time we tell the store: "I need the setUserInfo function"
  const setUserInfo = useUserStore((state) => state.setUserInfo);

  const handleFakeLogin = () => {
    // Assume API login succeeds, directly store data in global store!
    setUserInfo({ name: 'Boss Wang', role: 'admin' });
    alert('Login successful! Check if the Navbar name changes.');
  };

  return (
    <button onClick={handleFakeLogin} className="bg-blue-500 text-white p-2 rounded">
      Simulate Login
    </button>
  );
}

You'll notice that Navbar and Login are completely independent components, but as soon as Login executes setUserInfo, the text in Navbar instantly changes to "Boss Wang"! This is the powerful magic of global state.

๐Ÿ’ผ [Business Scenario] What Belongs in Zustand?

A common mistake beginners make after learning Zustand is stuffing all variables (including half-typed form inputs, modal toggle states) into Zustand. This leads to memory bloat and maintenance nightmares.

Remember this business principle: "Only shared data needed across multiple pages/components belongs in Zustand."

  • โœ… Suitable for: Logged-in user info, site-wide dark/light mode, shopping cart items.
  • โŒ Not suitable for: Page-specific Data Table search keywords, whether a button shows a confirmation dialog (use useState for these).

โœ… Chapter Summary

Mastering Zustand means your React project architecture has truly left the "beginner village".
No matter how complex an e-commerce system you build in the future, as long as you extract cross-page data into Zustand, your component tree will remain clean and organized. This is your strongest moat for staying sane when developing large-scale enterprise projects!

Unlock Full Tutorial

This chapter is paid content. Join the project to unlock over 5000 words of deep analysis, including 10+ god-tier Prompts and real Source Code examples!