DEV Community

Gustavo Isensee
Gustavo Isensee

Posted on

🏃‍♂️State management with Zustand!

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
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

 

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)