4

Zustand’s Guide to Simple State Management

 3 years ago
source link: https://blog.bitsrc.io/zustands-guide-to-simple-state-management-12c654c69990
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Zustand’s Guide to Simple State Management

React state management has evolved a lot during the past few years. Many have moved from Flux to Redux and looking for even more straightforward solutions. Also, the advent of React Hooks has opened up new avenues for state management.

Some of the new state management libraries that came into the picture are Recoil, Jotai, Radio Active state, and Zustand.

In this article, I will explore Zustand, which provides a lightweight and straightforward way of managing state in React.

What is Zustand?

Zustand is an open-source state management library developed by Jotai and React-spring’s (The best React animation library) creators. It has already gained traction with more than 50000 weekly downloads.

It is one of the lightest state management libraries available right now, with 1.5 KB in size. Even though it’s light-weight, it addresses some critical challenges like,

What makes it different ?

You might wonder why the same creators Jotai, created Zustand? These two contrasting approaches. Jotai aims to provide a simple solution for useState and useContext by creating an atomic state (just like recoil).

Zustand uses an external store, and it provides some Hooks to connect the external.

Then, isn’t it more like Redux? If we compare Zustand with Redux, one of the main differences is the boilerplate code it requires. Zustand requires less due to its opinionated approach. Besides, the combination of the following features make it unique;

  • It doesn’t wrap the application in context providers.
  • It allows adding subscriber functions to enable components to bind to state without re-rendering on Transient updates.
  • Uses Memoizing selectors, and React’s useCallback API function allows React to optimize performance in concurrent mode.
  • It supports Middleware quite well. You can hook it up with libraries like Immer to reduce code in reducers and make changes to a nested state.

Get started with React and Zustand

Let’s see how Zustand works with React. To demonstrate its capabilities, I will be creating a small Pokemon application. This application consists of a store, a list component, and an input form that handles the user’s input.

Step 01: Installation

Installing Zustand is as straight forwards as installing any of the npm packages. First, let’s install it using either npm or yarn.

npm install zustand
yarn add zustand

Step 02: Creating the store

Next, let's create the store just like any other state management library.

import create from "zustand";const useStore = create((set) => ({
pokemons: [{ id: 1, name: "Bulbasaur" },
{ id: 2, name: "Ivysaur" },
{ id: 3, name: "Venusaur" },
{ id: 4, name: "Charmander" },
{ id: 5, name: "Charmeleon" },
],addPokemons: (pokemon) =>
set((state) => ({
pokemons: [
{ name: pokemon.name, id: Math.random() * 100 },
...state.pokemons,
]})),removePokemon: (id) =>
set((state) => ({
pokemons: state.pokemons.filter((pokemon) => pokemon.id !== id),
})),
}));export default useStore;

A store is created through the Create API of Zustand, and the actions can be created as shown above. This store can be accessed throughout the application without using any Provider HOC(Higher-order component) like Redux.

Step 03: Accessing store state

Zustand is not entirely bound to React. It could be used with any other libraries like Vue or Angular. Let’s see how we can access the store from a component.

Accessing the store state and display the data in list view

import useStore from "../store";function List() {
const pokemons = useStore((state) => state.pokemons);
const removePokemon = useStore((state) => state.removePokemon);return (
<div className="row">
<div className="col-md-4"></div>
<div className="col-md-4">
<ul>{pokemons.map((pokemon) => (
<li key={pokemon.id}>
<div className="row">
<div className="col-md-6">{pokemon.name} </div>
<div className="col-md-6">
<button className="btn btn-outline-secondary btn-sm"
onClick={(e) => removePokemon(pokemon.id)}>X
</button>
</div>
</div>
</li>
))}
</ul>
</div>
<div className="col-md-4"></div>
</div>);
}
export default List;

Updating the state using a form

import { useState } from "react";
import useStore from "../store";

function Form() {
const [name, setName] = useState("");
const addPokemons = useStore((state) => state.addPokemons);

const onChange = (e) => {
setName(e.target.value);
};

const addPokemon = () => {
addPokemons({ name: name });
clear();
};

const clear = () => setName("");

return (
<div className="row">
<div className="col-md-2"></div>
<div className="col-md-6">
<input
type="text"
className="form-control"
onChange={onChange}
value={name}
></input>
</div>
<div className="col-md-2">
<button
className="btn btn-outline-primary"
onClick={(e) => addPokemon()}
>
Add
</button>
</div>
<div className="col-md-2"></div>
</div>
);
}

export default Form;

As you can see, Zustand is much more precise and straightforward than Redux, Recoil, or Jotai.

Step o4: Handling async actions

One of the real-world applications of Zustand action is to fetch data from a REST API. These actions we must execute asynchronously.

import axios from "axios";const useStore = create(set => ({
pokemons: [],
getPokemons: async ()=> {
const response = await axios.get('')
set({ pokemons: response.data })
}
}))

Async action can be handle just by using async/await in JavaScript. In the above example, you can see how async actions are fired through Axios.

Step 05: Middleware for Zustand

Zustand has some unique middleware out of the box. The most prominent middlewares are the dev tools (uses Redux dev tools) and Persist, which can persist data in the browser.

let useStore : (set)=>{
/* state and actions */
};useStore= persist(useStore, { name: 'Bulbasaur' }) useStore= devtools(useStore)export default useStore = create(useStore);
1*JLi6RlVsBf_Xq5e4DDY8AQ.png?q=20
zustands-guide-to-simple-state-management-12c654c69990
Zustand with dev tools middleware (uses redux devtools)

With Zustand, you can create your custom middleware and plugin as well.

Conclusion

In conclusion, the Zustand library is one of the lightest state management libraries out there. It also provides the flexibility to extend its functionality through plugins and middleware to enhance the development experience.

For example, Zustand allows accessing store outside React and compatible with Redux DevTools, Persist, and support for React Hooks, TypeScript, etc.

Therefore, Zustand looks to be an excellent candidate to consider for state management. The simplicity of the library also makes it a good option for beginners for state management with React.

At last, thank you for taking the time to read this. I would like to see your questions and comments below.

Cheers!

Build & share independent components with Bit

Bit is an ultra-extensible tool that lets you create truly modular applicationswith independently authored, versioned, and maintained components.

Use it to build modular apps & design systems, author and deliver micro frontends, or simply share components between applications.

Example: A remote scope with independent components available to be used and collaborated on

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK