Skip to content

cu-fs1/zustand

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 

Repository files navigation

🐻 Zustand: Simple & Professional React State Management

Welcome students! Today we're diving into Zustand, one of the most popular state management libraries in 2026. Unlike Redux or Context API, it’s famous for being extremely "bearbones," lightweight, and incredibly fast to get started with.


πŸ”οΈ What is Zustand?

"Zustand" is German for "state." It’s a small, fast, and scalable state-management solution for React.

Why choose it over Redux or Context API?

  1. Zero Boilerplate: No need to create Actions, Reducers, or Types (unless you really want to).
  2. No Providers Needed: You don't have to wrap your entire app in a <Provider>.
  3. High Performance: It only re-renders the components that actually use the piece of state that changed.
  4. Hook-Based: It feels exactly like using a custom React hook.

πŸš€ Getting Started

First, install the package using your favorite manager:

pnpm add zustand

πŸ› οΈ Step 1: Create Your Store

A "Store" is where your state lives. In Zustand, your store is also a hook!

import { create } from 'zustand';

// Think of 'set' as a way to update the state
const useBearStore = create((set) => ({
  bears: 0,
  
  // Actions to update state
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  
  removeAllBears: () => set({ bears: 0 }),
  
  updateBears: (newCount) => set({ bears: newCount }),
}));

export default useBearStore;

🎣 Step 2: Use the Store in Components

You can use your store hook anywhere in your application. To keep your app fast, always use Selectors to pick only what you need.

import useBearStore from './store';

function BearCounter() {
  // Selector: This component ONLY cares about 'bears'
  const bears = useBearStore((state) => state.bears);
  
  return <h1>{bears} bears are in the forest! 🐻</h1>;
}

function Controls() {
  // Selector: This component ONLY cares about the 'increasePopulation' action
  const increase = useBearStore((state) => state.increasePopulation);
  
  return <button onClick={increase}>Add a Bear</button>;
}

⚑ Async Actions (Fetching Data)

In other libraries, you need middleware (like Thunks) for async tasks. In Zustand, you just write an async function!

const useUserStore = create((set) => ({
  users: [],
  isLoading: false,

  fetchUsers: async () => {
    set({ isLoading: true });
    try {
      const res = await fetch('https://jsonplaceholder.typicode.com/users');
      const data = await res.json();
      set({ users: data, isLoading: false });
    } catch (error) {
      console.error("Failed to fetch users", error);
      set({ isLoading: false });
    }
  }
}));

πŸ’Ύ Persistence (Saving State)

What if you want your state (like a shopping cart or user theme) to stay even after the user refreshes the page?

Zustand provides a built-in middleware called persist.

Basic Setup

import { create } from 'zustand';
import { persist } from 'zustand/middleware';

const useCartStore = create(
  persist(
    (set) => ({
      items: [],
      addItem: (newItem) => set((state) => ({ 
        items: [...state.items, newItem] 
      })),
    }),
    {
      name: 'shopping-cart', // unique name for localStorage key
    }
  )
);

Advanced Persistence Options

  1. Partialize: Only save specific parts of your state.
    {
      name: 'user-storage',
      partialize: (state) => ({ token: state.token }), // don't save passwords or large objects!
    }
  2. Storage Type: Switch to sessionStorage if you want state to clear when the tab closes.
    import { createJSONStorage } from 'zustand/middleware'
    
    {
      name: 'food-storage',
      storage: createJSONStorage(() => sessionStorage), 
    }

πŸ†š Zustand vs. The Alternatives

Feature Zustand Redux Toolkit Context API
Learning Curve Gentle / Easy Steep / Complex Easy
Boilerplate 🐻 Minimal 🧱 Heavy πŸ› οΈ Moderate
Performance ⚑ High (Selective) ⚑ High (Selective) 🐒 Low (Full re-renders)
Setup ⏱️ Seconds ⏱️ Minutes ⏱️ Seconds
Persistence πŸ’Ύ Built-in Middleware πŸ”Œ External (Redux-Persist) πŸ› οΈ Manual Implementation

πŸ’‘ Best Practices for Students

  1. Always use Selectors: Instead of const state = useStore(), use const count = useStore(state => state.count). This prevents unnecessary re-renders.
  2. Keep it Simple: Don't over-engineer. Most apps only need a single store for global state.
  3. Persist Wisely: Only persist what is absolutely necessary. Storing too much in localStorage can slow down your app initialization.

πŸ“ Exercise for You:

  1. Create a useCartStore with an array for items.
  2. Add an action addItem that takes an object and adds it to the list.
  3. Challenge: Use the persist middleware to ensure the items stay in the cart after a page refresh!
  4. Display the total number of items in a navbar component.

Happy Coding! Learn more at zustand.docs.pmnd.rs

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors