Managing State in React with Zustand
State management in React can get pretty messy if you don’t pick the right tool. You start with useState
, then you raise it up to useContext
, then suddenly your app feels like it's participating in a circus and juggling props all over the place. That’s where Zustand strolls in, clean and minimal, like that one friend who doesn’t overcomplicate dinner plans.
Let’s explore how to manage a list of users across multiple components using Zustand.
Why Zustand?
Zustand is a small but powerful state management library. Unlike Redux (which sometimes feels like filing taxes), Zustand has no boilerplate ceremony, just plain simple functions.
Key benefits:
- Tiny and fast 🏎️
- No reducers, actions, or ceremony 🎉
- Works great with React hooks 👌
Basic Requirements Recap
To run this little app, you just need:
- React (v18+)
- Node & npm installed
-
zustand
package installed
Setting Up the Store
Let’s create a store for our users.
npm install zustand
Now, define a store:
// store/userStore.js
import { create } from 'zustand';
const useUserStore = create((set) => ({
users: [],
addUser: (newUser) =>
set((state) => ({
users: [...state.users, newUser],
})),
removeUser: (id) =>
set((state) => ({
users: state.users.filter(user => user.id !== id),
})),
}));
export default useUserStore;
Here’s what’s happening:
-
users
holds our list of users. -
addUser
lets us push a new user. -
removeUser
helps us clean up users 👋.
Displaying the User List
We’ll need a component to show the users.
// components/UserList.js
import React from 'react';
import useUserStore from '../store/userStore';
function UserList() {
const users = useUserStore((state) => state.users);
const removeUser = useUserStore((state) => state.removeUser);
return (
<div>
<h2>User List</h2>
<ul>
{users.map((user) => (
<li key={user.id}>
{user.name}
<button onClick={() => removeUser(user.id)}>❌</button>
</li>
))}
</ul>
</div>
);
}
export default UserList;
Here, we’re pulling users directly from the store with useUserStore
. No prop drilling. No tears.
Adding a New User
We also need a form (or a button) to add users.
// components/AddUser.js
import React, { useState } from 'react';
import useUserStore from '../store/userStore';
function AddUser() {
const [name, setName] = useState('');
const addUser = useUserStore((state) => state.addUser);
const handleSubmit = (e) => {
e.preventDefault();
if (!name.trim()) return;
addUser({ id: Date.now(), name });
setName('');
};
return (
<form onSubmit={handleSubmit}>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter user name"
/>
<button type="submit">Add User</button>
</form>
);
}
export default AddUser;
Now you have a way to actually add new users.
Putting It Together
Finally, use both components in your App
.
// App.js
import React from 'react';
import AddUser from './components/AddUser';
import UserList from './components/UserList';
function App() {
return (
<div>
<h1>Zustand User Management 🐻</h1>
<AddUser />
<UserList />
</div>
);
}
export default App;
Final Thoughts
Zustand makes state management less painful. Instead of dealing with reducers and dispatchers (hello, Redux), you just call functions. Your code stays readable, and your state stays centralized.
Top comments (0)