Why Zustand is the Perfect State Management Solution for Your React Project

Why Zustand is the Perfect State Management Solution for Your React Project

Introduction

I was building an application that required a common state, specifically an array where I needed to push objects and display them. Initially, I used prop drilling to manage the state, which worked fine until I encountered nested components. Passing the state from one component to another became a real pain. That’s when I discovered Zustand, a global state manager that turned out to be a lifesaver!

Why Zustand Over Other State Management Solutions?

React has various alternatives for state management, including Redux, the Context API, and MobX. Each has unique qualities, but Zustand stands out for a variety of reasons. I first explored Redux for my medium-scale application, but it required a lot of boilerplate code and had a difficult setup. This drove me to move to Zustand, which was much simpler to use. Not only that but , it had various features:

  • Simplicity

  • Flexibility

  • No Middleware Required

Now that you've gained a better knowledge of Zustand, let's put it into action in an application.

Installation

npm install zustand

As simple as that!

Incorporate Zustand into your application

Once you've installed Zustand in your next-app, go ahead and create a folder named "zustand" in the root directory. Inside this "zustand" directory, create a file named "store.js"(or any other name). If you have a components directory already set up, you can create the "store.js" file within that directory instead.

What is store.js?

It acts as a container for your application's state. It provides a way to manage and access this state across different parts of your application. Think of it as a centralized storage space where you can keep track of data that needs to be shared and manipulated throughout your app. In simpler terms it is provides all the common states for the application.

let's establish a centralized state management solution


store.js

import { create } from 'zustand'

const useStore = create((set) => ({
  count: 1,
  inc: () => set((state) => ({ count: state.count + 1 })),
}))

export default useStore

The above code snippet demonstrates how to create a Zustand store using the create function provided by Zustand.

First, we import the create function from 'zustand'. Then, we define a custom hook named useStore using create. Inside the create function, we specify the initial state of our store and the actions that can modify that state.

Initial State

The initial state variable count is initialized to 1. This will be the default value to start with.

Actions

Actions are functions that perform specific tasks, like updating the state of your application. For example, the inc action in the above code increases the count by one whenever it's called.

Note: We can include multiple functions/actions that modify the state when called.

For example:

dec: () => set((state) => ({ count: state.count - 1 }))

This dec function decrements the count by one whenever it's called.


Implementing and Linking Components with the Store

First create a navigation bar component and embed into the main page of your react app

navbar component:


import useStore from "@/zustand/store";

const Navbar = () => {

  const inc = useStore((state) => state.inc);

  return (
    <div className="h-20 bg-blue-100 flex items-center justify-center">
      <div>
        <button className="bg-red-500 text-white p-2 border-2" onClick={inc}>
          Increase
        </button>
      </div>
    </div>
  )
}

export default Navbar
  1. Import useStore from your Zustand store (@/zustand/store): This is a hook provided by Zustand to access and manipulate the global state.

  2. Create an instance of the useStore : inc = useStore((state) =>state.inc); This line uses the useStore hook to access the inc function from the Zustand store. The inc function is the state updater as discussed previously.

  3. Now in the JSX return statement , create a button element and set its onClick event to call the inc function.

    You are done setting up the navbar component and now lets setup the main page.

main page:

"use client"
import Navbar from "@/components/navbar";
import useStore from "@/zustand/store";

const page = () => {
  const count = useStore((state) => state.count);
  const inc = useStore((state) => state.inc);

  return (
    <>
      <Navbar />
      <div>
        <div className="m-10 text-5xl">
          {count}
        </div>
        <button onClick={inc} className="m-10 bg-red-500 p-2">Increase</button>
      </div> 
    </>
  )
}

export default page
  • Similarly to the navbar component, we import the useStore and create an instance of it. Following that, we need to add a count state to show the count and an inc method to increase it.

    count state : inc = useStore((state) =>state.inc);

  • In the JSX return statement , create a button element and set its onClick event to call the inc function and also a division to display the count.

  • Now host the application on local.

Demonstration

Once the application is hosted, you will notice that clicking any of the buttons across different components results in an incrementing count without actually passing it through props.

Voilà! This simple demonstration is highly beneficial for developing a full-stack application.

Check out the demonstration here Zustand Demonstration

Check out the code here GitHub Code

Conclusion

Zustand is a very useful tool which is very easy to understand and implement. I would highly recommend it over Redux in a small to medium sized web application.

I hope you found this article helpful. Thanks for reading 🙏

Let's connect. I will eventually share more interesting and useful stuff.