2f2006a6167035f79226
·4 min read

Zustand - The Redux Alternative

react
zustand
redux
state
4d5fd787ac74e0caa4f7

Sohan R. Emon

Developer, Learner, Tech Enthusiast

You might have heard of Redux, a popular library for managing your app's state. But Redux can be quite complex and verbose, which is where Zustand comes in as a simpler alternative.

What is Zustand?

Zustand is a state management library for React applications. It's like Redux but with a much easier and more intuitive API. With Zustand, you can handle your app's state in a more organized and scalable way without drowning in boilerplate code.

Creating a Store

In Zustand, creating a store is a breeze. You can define your store using the create function. Here's a simple example:

tsx
import { create } from "zustand";

const store = (set, get) => ({
  value: 0,
  inc: (p) => {
    set((s) => ({ ...s, value: s.value + p }));
  },
  dec: () => set((s) => ({ ...s, value: get().value + 1 })),
});

export const useCounter = create(store);

Here, set is similar to setState, and p is like the payload in Redux. However, in Zustand, the payload goes through a reducer, not directly to set. You can also pass additional parameters to set to control its behavior.

Fetching Data from the Store

Fetching data from the Zustand store is simple and flexible. You can pick exactly what you need:

tsx
const { value, inc } = useCounter(); // Fetching all
// or
const inc = useCounter((state) => state.inc); // Fetching specific
// or
const [value, inc] = useCounter((state) => [state.value, state.inc]); // Array pick
// or
const { value, inc } = useCounter((state) => ({ value: state.value, inc: state.inc })); // Object pick

Zustand/Shallow

If you want to optimize performance and prevent unnecessary re-renders, you can use zustand/shallow like this:

jsx
import { shallow } from 'zustand/shallow';
import { useStore } from './store';

function MyComponent() {
  const { name, age } = useStore(state => ({ name: state.name, age: state.age }), shallow);

  // Do something with name and age...

  return <div>{name} is {age} years old.</div>;
}

Using Zustand Outside Components

Zustand isn't just for use within React components; you can use it in utility functions or libraries too:

jsx
// Get the current state
const state = useStore.getState();

// Call the increment method
useStore.getState().inc();
// or
state.inc();

Subscribing to State Changes

You can subscribe to state changes with the subscribe method. It calls a callback function whenever the state changes:

jsx
import { create } from "zustand";

const store = (set) => ({
  value: 0,
  inc: (p) => {
    set((s) => ({ ...s, value: s.value + p }));
  },
});

export const useCounter = create(store);

// Subscribe to changes
useCounter.subscribe(
  (state) => console.log("New state:", state),
  (state) => state.value === 2 // Optional selector function to limit updates
);

Middleware - Supercharge Zustand

Zustand comes with several middleware options to enhance its functionality.

Devtools - Redux Toolkit for Zustand

You can integrate the Redux DevTools with Zustand by adding the devtools middleware:

jsx
import create from 'zustand';
import { devtools } from 'zustand/middleware';

const store = (set) => ({
  value: 0,
  value2: 5,
  inc: (p) => {
    set((s) => ({ ...s, value: s.value + p }), false, 'inc');
  },
});

// Just wrap the store
export const useCounter = create(devtools(store));

Persist - Store on Local Storage

To persist your Zustand store on the user's local storage, use the persist middleware:

jsx
import create from "zustand";
import { persist } from "zustand/middleware";

const store = (set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
});

export const useCounter = create(persist(store), { name: "counter" });

This ensures that your app's state survives page refreshes.

Immer - Simplify State Updates

To simplify state updates, you can use the immer middleware with Zustand:

jsx
import create from 'zustand';
import { immer } from 'zustand/middleware';

const store = (set) => ({
  value: 0,
  inc: (p) => {
    set((state) => { state.value += p; });
  },
});

// Just wrap the store
export const useCounter = create(immer(store));

This makes updating your state even easier.

In summary, Zustand is a fantastic alternative to Redux for managing state in your React applications. It's simple, flexible, and offers various middleware options to supercharge your app's state management. Give it a try in your next project and experience the difference!

Found this useful?