State Management on React [Part 5] - Zustand
Tags: typescript, react, javascript, frontend
Published: 2023-06-11 20:12:47

## **What's up Folks!!**

It's nice to have you here again!!!
This is the fifth and **last** part of articles of react management. How are you feeling with so much technologies? Amazing, isn’t it?


![SpongeBob Tired Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xn90ivww3tfn4bf6a45a.png)


I hope you guys liked the previous article where I talk about state management using the Recoil. If you did not saw the previous part you can find here: [Recoil State Management](https://dev.to/kevin-uehara/state-management-on-react-part-4-recoil-55mp)

We are going to create a simple application but we will be able to see the code of the technologies and compare the implementation.

Just to remember, let's get situated:

- [**Context API (part 1)**](https://dev.to/kevin-uehara/state-management-on-react-part-1-context-api-4jig)
- [**Redux (part 2)**](https://dev.to/kevin-uehara/state-management-on-react-part-2-redux-n5f)
- [**Jotai (part 3)**](https://dev.to/kevin-uehara/state-management-on-react-part-3-jotai-i7f)
- [**Recoil (part 4)**](https://dev.to/kevin-uehara/state-management-on-react-part-4-recoil-55mp)
- [**Zustand (part 5)**](https://dev.to/kevin-uehara/state-management-on-react-part-5-zustand-1jl3)

**Summary:**
- [**Introduction**](#introduction)
- [**Show me the code**](#show-me-the-code)
- [**Results**](#results)
- [**Conclusion**](#conclusion)

## Introduction

Zustand is comparable to Redux, as Jotai with Recoil.

According to the documentation of zustand:

>A small, fast and scalable bearbones state-management solution using simplified flux principles. Has a comfy API based on hooks, isn't boilerplatey or opinionated.

>Don't disregard it because it's cute. It has quite the claws, lots of time was spent dealing with common pitfalls, like the dreaded zombie child problem, react concurrency, and context loss between mixed renderers. It may be the one state-manager in the React space that gets all of these right.

![Zustand Image of main page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/onbnzpi3wusu6rvdp6pj.png)

Just to remember again (sorry but it's important), if you did not saw the first part, I created all components that we will use in this and next parts on the first part. Soooo if you did not saw yet, I recommend to see on: [State Management on React [Part 1] - Context API.](https://dev.to/kevin-uehara/state-management-on-react-part-1-context-api-4jig)

We will use the first version of the components that we created without the Context API integration.

Now with all concepts at hands, LET'S TO THE CODE!

## Show me the code

Let's add the dependencies that we will use:

```sh
yarn add zustand
```
easy peasy!

And now, we don't need to a provider on our `main.txt`.

So I will create a directory on `/src` called `store` and for each feature I will create a folder with the name of the feature. So, we have two features in our app: change theme color (dark mode) and a todo list:

![Image of directory’s](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uquxyb4j7ibs1dm5psrm.png)

Let's start with the dark mode feature. We will create a file on store/theme/index.ts and create this code:

```ts
import { create } from "zustand";

export interface ITheme {
  isDark: boolean;
  changeTheme: VoidFunction;
}

export const useTheme = create<ITheme>((set) => ({
  isDark: false,
  changeTheme: () => {
    set((state: ITheme) => ({ isDark: !state.isDark }));
  },
}));
```

I'm using an interface to define our typess on our zustand hooks to manage the state. Zustand offers the `create` function to we manage the state.

Now let's see how the todo store will it be.

Let's create on store/theme two files. First the types types.ts (my preference) and the index.ts.

The types.ts contains just the type of our todo:

### store/todo/types.ts

```ts
export interface ITodo {
  id: number;
  text: string;
  done: boolean;
}

export interface ITodoState {
  todos: ITodo[];
  addTodo: (text: string) => void;
  removeTodo: (id: number) => void;
}
```

And creating the store for our todo list on index.ts and the code will be:

### store/todo/index.ts

```ts
import { create } from "zustand";
import { ITodo, ITodoState } from "./types";

export const useTodo = create<ITodoState>((set) => ({
  todos: [],
  addTodo: (text: string) => {
    const newTodo: ITodo = {
      id: Math.random() * 1000,
      text,
      done: false,
    };

    set((state: ITodoState) => ({
      todos: [...state.todos, newTodo],
    }));
  },
  removeTodo: (id: number) => {
    set((state: ITodoState) => ({
      todos: state.todos.filter((todo) => todo.id !== id),
    }));
  },
}));
```

The `create` function pass the `set` parameter for we update the state. Now we can see the similarities with redux, when I introduce the slicers.

Now we will change the components to use our zustand state.

First, let's change the ButtonChangeTheme:

### components/ButtonChangeTheme/index.tsx

```tsx
import { ITheme, useTheme } from "../../store/theme";
import button from "./button.module.css";

interface ButtonChangeThemeProps {
  label: string;
}

export const ButtonChangeTheme = ({ label }: ButtonChangeThemeProps) => {
  const changeColor = useTheme((state: ITheme) => state.changeTheme);

  return (
    <button className={button.btn} onClick={changeColor}>
      {label}
    </button>
  );
};
```

We just need to use the hook that we created and get the function that we created.

Now changing the `Content` dummy component:

### components/Content/index.tsx

```tsx
import { ITheme, useTheme } from "../../store/theme";

interface ContentProps {
  text: string;
}

export const Content = ({ text }: ContentProps) => {
  const isDark = useTheme((state: ITheme) => state.isDark);

  return (
    <div
      style={{
        height: "30vh",
        width: "100vw",
        color: isDark ? "#fff" : "#111827",
        backgroundColor: isDark ? "#111827" : "#fff",
      }}
    >
      {text}
    </div>
  );
};
```

The same thing will happens on FormTodo and ListTodo:

### components/FormTodo/index.tsx

```tsx
import style from "./Form.module.css";
import { Button } from "../Button";
import { Input } from "../Input";
import { useState } from "react";
import { useTodo } from "../../store/todo";
import { ITodoState } from "../../store/todo/types";

export const FormTodo = () => {
  const [todo, setTodo] = useState("");
  const addTodo = useTodo((state: ITodoState) => state.addTodo);

  const handleAddTodo = () => {
    addTodo(todo);
    setTodo("");
  };

  return (
    <div className={style.formContainer}>
      <Input
        value={todo}
        label="Todo"
        onChange={(evt) => setTodo(evt.target.value)}
      />
      <Button label="Adicionar" onClick={handleAddTodo} />
    </div>
  );
};
```

### components/ListTodo/index.tsx

```tsx
import { useTodo } from "../../store/todo";
import { ITodoState } from "../../store/todo/types";
import style from "./ListTodo.module.css";

export const ListTodo = () => {
  const removeTodo = useTodo((state: ITodoState) => state.removeTodo);
  const todos = useTodo((state: ITodoState) => state.todos);

  return (
    <ul>
      {todos.map((todo) => (
        <li className={style.item} key={todo.id}>
          <label>{todo.text}</label>
          <i className={style.removeIcon} onClick={() => removeTodo(todo.id)} />
        </li>
      ))}
    </ul>
  );
};
```

And for the fourth time we finish the same app!

## Results

Zustand has many similarities with Redux.

But what I introduced to you it's just the basic of Zustand. Read the [documentation](https://github.com/pmndrs/zustand) to see more details.

The visual will not change but let's see 👀 using the React Dev Tools with highlighting render:

![Zustand highlight gif dev tolls](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xzpi4esg3qtvsem2av1j.gif)

And the React Dev Tools Profiler:

![Zustand Profiler git dev tools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w08z45vj90og4b0lxr2h.gif)

## Conclusion

Zustand is  offers a minimal API to manager our state. It simple and easy to maintain our state.

But different of Redux, zustand offers:
- Makes hooks the primary means of consuming state
- Doesn't wrap your app in context providers
- Less boilerplate

I'm not saying that zustand is the best library and that you should use it in all your project. Or that all the state managers that I introduce to you are the best. 

Like everything in computing the answer is: it depends.
It depends of your project, product, solution, team, knowledges and a lot of more...

So much so that the purpose of these articles is to compare the application and implementation of each state manager.

So in summary, in this article we saw how we can implement the zustand and manipulate our global state.

It was a pleasure to bring this content to you. I hope I have somehow added some knowledge or brought some technology that can help you.

It's been a long journey, but we're done here. See you in some upcoming articles. Thank you very much.

Some references:

- [Zustand](https://github.com/pmndrs/zustand)
- [My repository](https://github.com/kevinuehara/react-state-management)
- [Linkedin](https://www.linkedin.com/in/kevin-uehara/)

That's all folks!

Thank you so much!!!


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f0kaeb4n1plytukwdmru.gif)