DEV Community

Cover image for Simplifying State Management with React Hooks using Zustand
Ankur Kedia
Ankur Kedia

Posted on • Edited on • Originally published at ankurkedia.com

Simplifying State Management with React Hooks using Zustand

Article originally posted on my blog.


State management is probably one of the hardest parts of app development. More importantly, it is also the most crucial part to get right. This article is about simplifying the state management of your app with no new concepts. We will use Zustand to solve this which has hooks at its core. Covering the basics in this article, we will create a simple todo app. Since React Hooks are used to perform all the operations, basic hooks knowledge is all you'll need to sail through state management with Zustand.

What is Zustand?

Zustand is a simple, lightweight, fast, and React hooks-based state management.

A small, fast and scaleable barebones state-management solution. Has a comfy API based on hooks, isn't boilerplate-y or opinionated, but still just enough to be explicit and flux-like.

Features

  • Lightweight.
  • Little(hooks) or no learning curve.
  • Makes hooks the primary means of consuming state.
  • Not opinionated.
  • Transient updates.

Apart from the convenience, Zustand solves some of the common problems with other libraries like complex flows, over-engineered solutions. It also solves some common documented issues with major existing libraries and patterns like the Context loss issue, React concurrency issues, Zombie child problem.

How to use it?

To demonstrate, we will create a basic todo app with CRUD operations. We will start with creating a store. Then, initialize an array of todos and add a function to add a todo to the list.

import create from 'zustand';

const useStore = create((set) => ({
  todos: [],
  add: (title) =>
    set((state) => ({ todos: [...state.todos, { title }] }))
}));
Enter fullscreen mode Exit fullscreen mode

Then, we attach the state todos we defined in the store to our components.

import { useStore } from './store';

function TodoList() {
  const todos = useStore((state) => state.todos);
  return (
    <div>
      {todos.map(({ title }) => (
        <div>{title}</div>
      ))}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Finally, we attach the add function which we defined to our button element. We will pass the input value as the title for the todo item.

import { useStore } from './store';

function TodoInput() {
  const [inputValue, setInputValue] = React.useState('');
  const add = useStore((state) => state.add);
  return (
    <div>
      <input
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
      />
      <button onClick={() => add(inputValue)}> Add </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Et voila, we have a rudimentary version of the todo app working. The same patterns of get and set can be used across the app for all sorts of operations. We have also created the toggleDone and remove functions along the same line. You can check the sandbox below for the complete functionality.

Advanced features

For large projects, we need a lot more than just CRUD operations, but Zustand has got you covered there too. It already has support for the following:

  • Async operations: You just need to call set whenever you're ready, it doesn't matter if your actions are async or not.
  • Middlewares: Compose and pipe your middlewares any way you like.
  • *Multiple stores fetching *: You can create as many selectors as you like.
  • Devtools: Provides an in-built devtool middleware.
  • Usage with Redux: If you still want to use reducer and action pattern, you can follow it here too.
  • Handling nested states: Manipulating nested structures is tedious. You can use immer as a middleware though.

Disadvantages

Although Zustand's documentation is concise, has a good flow, and is very easy to understand, it could use some more detailing and example in some sections like handling multiple middlewares, managing nested states, code optimizations for better performance. So, please considering contributing to Zustand.

Caution: You Might Not Need Redux(or any other state management library)

Conclusion

Using Zustand is very convenient and you don't need a load of information to get started. When comparing with seasoned state management solutions, it definitely has an edge when it comes to DX. Its simplicity, flexibility, and unopinionated nature make it a compelling option. So, if you are a beginner in handling state management or if you have a project that does not deal with deeply nested structures, then Zustand might be a great fit for your project.

Top comments (0)