Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Zustand Fundamentals: Beyond React Context

Hello! Welcome to your first lesson on Zustand.

Given your extensive experience with React and state management libraries like Redux and MobX, we can dive straight into the specifics of what makes Zustand a compelling choice. This first lesson focuses on its fundamental principles and, most importantly, how it addresses the common performance pitfalls of using React's built-in Context API for global state.

By the end of this lesson, you will be able to describe the core principles of Zustand and its advantages over React Context for state management.

Let's get started.

1. The State of State Management in React

As you know, managing state that needs to be shared across many components is a central challenge in React development. While useState is perfect for local component state, sharing it globally often leads to two common solutions:

  1. Prop Drilling: Manually passing props down through multiple layers of components. This becomes unwieldy and difficult to maintain quickly.
  2. React Context API: React's built-in solution to avoid prop drilling by creating a global "context" that any component in the tree can subscribe to.

While the Context API is a significant improvement over prop drilling, it has a critical performance limitation, especially in large applications. This limitation is the primary problem that libraries like Zustand aim to solve.

2. What is Zustand? Core Principles

Zustand (German for "state") is a small, fast, and scalable state management solution. It's often described as taking the best ideas from Flux/Redux but simplifying them into a minimal, hooks-based API.

To get a quick feel for its philosophy and a look at a basic store, please watch this short segment from the video "Why Everyone Loves Zustand" by Theo - t3.gg.

Why Everyone Loves Zustand

This clip introduces Zustand and shows a simple code example of creating a store. Notice how it uses a single create function and returns a hook.

Watch from 01:52 to 02:54 to understand what Zustand is at a high level and see the basic syntax for creating a store.

As you saw, the API is very concise. Here are the core principles that define Zustand:

  • Minimal Boilerplate: No need for actions, reducers, dispatchers, or context providers wrapping your entire application. You create a store with a single function, and it returns a hook that you can use immediately.
  • Hooks-based API: It's designed to feel native to modern React. You use a hook to access state, making it intuitive for anyone familiar with useState or useContext.
  • Performance via Selective Subscriptions: This is Zustand's key advantage. Components can subscribe to specific slices of the state, and they will only re-render when those specific slices change. We'll explore this in depth shortly.
  • Decoupled from React: The state logic is not tied to the React component lifecycle. You can access and modify the store from anywhere in your application, including utility functions or event listeners outside of your components.

3. The React Context Re-render Problem

Before we detail Zustand's advantages, let's solidify our understanding of the problem it solves. With the Context API, any component that consumes the context via useContext will re-render whenever any part of the context value changes, even if that component doesn't use the specific piece of state that was updated.

Imagine a context holding both user authentication status and a theme preference:

// A simplified example of a context value
const globalContextValue = {
  isAuthenticated: false,
  theme: 'dark',
  login: () => { /* ... */ },
  toggleTheme: () => { /* ... */ }
};

A UserProfile component might only care about isAuthenticated, and a ThemeToggleButton might only care about theme. With useContext, if the user toggles the theme, both the ThemeToggleButton and the UserProfile component will re-render, because the entire globalContextValue object is new. In a large application, this can cause a cascade of unnecessary re-renders, leading to significant performance issues.

This video segment explains this exact issue very clearly.

Why Everyone Loves Zustand

Here, the presenter discusses the primary drawback of using React Context for sharing state across multiple components.

Watch from 22:22 to 23:26. Focus on the explanation of why changing the context value causes all subscribed components to re-render.

4. Zustand's Advantages Over React Context

Zustand directly addresses the limitations of the Context API. Let's break down its main advantages.

Advantage 1: Optimized Performance with Selectors

This is the most significant advantage. Zustand avoids the "waterfall" re-render problem by allowing components to select only the pieces of state they need. This is done through a selector function.

When you use the store's hook, you can pass a function that takes the entire state and returns just the data your component depends on.

// Instead of this, which subscribes to the whole store:
const { count, user } = useStore();

// You do this, which subscribes ONLY to changes in `count`:
const count = useStore(state => state.count);

// Or this, which subscribes ONLY to changes in the `user` object:
const user = useStore(state => state.user);

Zustand performs a strict equality check (===) on the return value of your selector. The component only re-renders if the selected value has changed. This mechanism of selective subscription is the core of its performance optimization.

The following clip demonstrates this concept of granular state selection in practice.

Why Everyone Loves Zustand

This part of the video explains how selectors work in Zustand to ensure components only re-render when the specific state they care about changes.

Watch from 20:07 to 22:07. Pay close attention to how passing a selector function to the useStore hook isolates re-renders.

Advantage 2: Simplicity and Scalability

To further structure this comparison, please read the following article from dev.to. It provides a clear, side-by-side analysis.

React | Context API vs Zustand

This article, 'React | Context API vs Zustand', provides a concise comparison table and lists the pros and cons of each approach.

Read the sections 'Differences Between useContext and Zustand', 'Pros and Cons of useContext', and 'Pros and Cons of Zustand'. The comparison table is particularly useful for a quick overview.

As the article highlights, Zustand's advantages extend beyond just performance:

  • Less Boilerplate: You don't need to wrap your app in <MyContext.Provider>. This not only simplifies your App.js or root component but also makes it easier to introduce multiple, independent stores for different features without nesting providers.
  • Better for Complex State: While Context is suitable for low-frequency updates (like theming), Zustand is built to handle complex, high-frequency state changes gracefully. Its support for middleware (which we'll cover later) allows for powerful extensions like logging, persistence, and integration with devtools.
  • Lightweight: As mentioned in the first video, Zustand has a very small bundle size, adding minimal overhead to your application.

Key Takeaways

To conclude this lesson, let's summarize the core ideas:

  • Zustand's Core Principle: It's a minimal, hooks-based state management library that provides global state access without the ceremony of Redux or the performance issues of React Context.
  • The Problem with React Context: It causes all consuming components to re-render when any part of the context value changes, leading to performance bottlenecks.
  • Zustand's Main Advantage: It solves the re-render problem through selective subscriptions using selector functions. Components only update when the specific state slices they depend on actually change.
  • Other Advantages: Zustand offers significantly less boilerplate, is easier to scale with complex state, and can be used outside of React components.

You now have a solid conceptual foundation of what Zustand is and why it's a powerful alternative to the React Context API for managing global state.

Next Lesson Preview

In the next lesson, we will broaden our comparison to include other popular state management libraries. The learning outcome will be: "Differentiate Zustand from Redux and MobX, focusing on boilerplate, API simplicity, and performance characteristics." This will be a great opportunity to leverage your existing knowledge of these libraries to further contextualize Zustand's place in the React ecosystem.

Can't find a good explanation? Sign up and we'll make it for you

Sign up