Easily Master the React State Management with Zustand
What is Zustand?
Zustand is a fast and scalable state management solution built by the developers of Jotai and React springs. Zustand is known for its simplicity and less boilerplate code.
Zustand provides the following key features:
- Simpler and un-opinionated
- Makes hooks the primary means of consuming state
- Doesn’t wrap your app into context providers
Let’s easily understand how Zustand can be used
Todo app
import create from "zustand";
export const useStore = create((set, get) => ({
todos: [],
getTodos: async () => {
let todos = await fetch("https://jsonplaceholder.typicode.com/todos");
todos = await todos.json();
set({ todos });
},
}));
Done, our Zustand store is ready 😂. No need to wrap your App with the Context provider 😎.
The main function of the state management library is called create
. It accepts a callback function as its first argument, which in turn accepts a set
function that should be used when manipulating the state.
Now let's break down
To understand easily, let’s compare it with useState hook from React, and let’s fetch some todos.
import { useState } from "React";
const App = () => {
const [todos, setTodos] = useState([]);
async function fetchTodos() {
let response = await fetch("https://jsonplaceholder.typicode.com/todos");
response = await response.json();
setTodos(response);
}
useEffect(() => {
fetchTodos();
}, [])
return <></>
}
export default App;
Now, this code might be similar to you, Usually, this is how we fetch data using useState and useEffect.
The same thing we are doing inside the zustand store that we have created.
- todos: [] → It is similar to useState hook in React.
- getTodos → In this function, we are simpling fetching our TODOS and changing the state (todos) by the set function. set is similar to setTodos().
See that inside our Zustand store, we have the getTodos function as async, this is one more important feature of zustand.
I hope now you might have understood what exactly is happening. If not, just go through it once more.
A Task for you, create a function that deletes all the todos. Do it both with useState hook and zustand.
In useState: setTodos([ ]);
In Zustand: deleteTodos: () => set({ todos: [ ] });
You got it right? Well done…
import create from "zustand";
export const useStore = create((set, get) => ({
todos: [],
getTodos: async () => {
let todos = await fetch("https://jsonplaceholder.typicode.com/todos");
todos = await todos.json();
set({ todos });
},
deleteTodos: () => set({ todos: [] })
}));
Now let’s create an simple UI
import { useStore } from "./utils/store";
export default function App() {
const { todos, getTodos, deleteTodos } = useStore();
return (
<div className="App">
<h1>Todos</h1>
<button onClick={getTodos}>Fetch Todos</button>
<button onClick={deleteTodos}>Delete Todos</button>
{todos.map((todo) => (
<h4>{todo.title}</h4>
))}
</div>
);
}
This code is straightforward, we are importing the useStore, and destructuring todos, getTodos, and deleteTodos.
When we click on Fetch Todos button, all the todos are fetched and displayed.
When we click on Delete Todos button, the todos are set to an empty array.
Play with the demo below.