I Tried Zustand… and It's Awesome!

I Tried Zustand… and It's Awesome!

Table of contents

No heading

No headings in the article.

Hi, guys!

A few days ago, I started rewriting the apps from my portfolio. For now, I have only rewritten one, but the others will follow soon. You might wonder why I'm doing that. Well, there are a couple of reasons. The first reason is that I love to try new things - new technologies, new tricks, etc. A second reason might be the Bored application I wrote some time ago. More precisely, it was a couple of years ago. It's so old that I wrote it in React using class-based components - just imagine that.

Throughout my five years of working and eight years of learning, I have come across many state management systems. But the state management systems I have worked with include Redux, Context API, and MobX. I have also briefly examined Jotai, but I haven't tried it yet - though I plan to.

I will mention a few words about them, but not too much because this blog post is primarily about Zustand.

MobX: I worked with MobX in a legacy project. The project was based on class-based components, and even though I still understand quite well how to work on this type of project, the MobX state manager seems to me not very developer-friendly. There was a lot of configuration and boiler-plating required to add new functionality.

Context API: It's suitable for small projects like this Bored app I have. However, for large projects, I don't think it's the best choice. You need to create a context/store for each component because if you don't, you'll experience numerous unnecessary re-renders, leading to poor performance.

Redux: Redux is excellent, and I'm thrilled with it. A few years ago, Redux Toolkit appeared, and it significantly reduced the complexity of setup. However, there's still a bit of boilerplate to do - not too much, but not too little.

And now, the moment you've been waiting for (drumroll, please) - ZUSTAND: I just tried Zustand, and it seems very refreshing and straightforward. There's minimal boilerplate. The main thing you need to do is define the type of the store. Usually, you'll have a state that holds the data/values and action(s), especially if you're using TypeScript. Let me show you a snippet to better understand what's going on.

import { create } from 'zustand'

const useBearStore = create((set) => ({
  bears: 0,
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 }),
}))

And then in your code, you can use it as follows:

function BearCounter() {
  const bears = useBearStore((state) => state.bears)
  return <h1>{bears} around here ...</h1>
}

function Controls() {
  const increasePopulation = useBearStore((state) => state.increasePopulation)
  return <button onClick={increasePopulation}>one up</button>
}

Currently, in the Bored app, I have only two states: one for DarkMode and one for Activity. That's why I put all the state into one file. But I genuinely believe it's a good pattern to declare each state for a feature. Let's say we have an application that has a user and a theming state.

We can declare the store as follows:

      — Profile
           — Profile.tsx
           — Profile.store.tsx
      — Theming
           — Theming.tsx
           — Theming.store.tsx

That's just one example that comes to mind. But I'm sure you can get very creative here.

Zustand offers much more than that; you can check the state using Redux Toolkit, use slices, and much more. You can check the documentation for more details.

Let me know your thoughts about Zustand and other state management systems.

I'll include the Bored application and GitHub links for the repo if you're interested in taking a look.

Here's a little spoiler: next, I'll write an article about UI/CSS Libraries, CSS in JS, etc.

Until next time!

Cheers!