DEV Community

Singh1106
Singh1106

Posted on

Why zustand over redux?

So as my first post, so hoping for a lot and lot of positive criticism. I will write about why I like zustand over redux. Both of them are in a way, exactly same, both are unidirectional state managers, but why is zustand better (more like why I like zustand more), keep reading to know.. haha, big suspense movies' fan here.

So we will start with an example of how to make a simple counter in redux:

Let's first of all create a react app.
npx create-react-app redux-tut

and now installing the dependencies needed

npm install @redux/toolkit react-redux

We have to install these 2 dependencies, to be able to use redux toolkit, which is supposed to be the latest and with least boilerplate.

Now in redux toolkit, one store has many slices, and every one of those slices, has their reducers and their actions and everything.

Now we will create a new slice for our counter.

Lets create a store folder in our src folder and a counterSlice.js folder in our store folder.

Redux Toolkit Slices store folder structure

and paste this in your counterSlice.js

import { createSlice } from "@reduxjs/toolkit";

export const slice = createSlice({
  name: "counter",
  initialState: {
    value: 0
  },
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    }
  }
});

export const { increment, decrement, incrementByAmount } = slice.actions;
export const selectCount = (state) => state.counter.value;

export default slice.reducer;
Enter fullscreen mode Exit fullscreen mode

Now in this counterSlice, we have 3 actions, increment and decrement by 1 and increment by value, and we can set the value.

and lets create a store and import this slice into that store.

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counterSlice";

export default configureStore({
  reducer: {
    counter: counterReducer
  }
});
Enter fullscreen mode Exit fullscreen mode

and now creating the Counter.js

import React, { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import {
  decrement,
  increment,
  incrementByAmount,
  selectCount,
} from "../store/counterSlice";

export function Counter() {
  const count = useSelector(selectCount);
  const dispatch = useDispatch();
  const [incrementAmount, setIncrementAmount] = useState("2");

  return (
    <div>
      <div>
        <button
          aria-label="Increment value"
          onClick={() => dispatch(increment())}
        >
          +
        </button>
        <span>{count}</span>
        <button
          aria-label="Decrement value"
          onClick={() => dispatch(decrement())}
        >
          -
        </button>
      </div>
      <div className>
        <input
          aria-label="Set increment amount"
          value={incrementAmount}
          onChange={(e) => setIncrementAmount(e.target.value)}
        />
        <button
          onClick={() =>
            dispatch(incrementByAmount(Number(incrementAmount) || 0))
          }
        >
          Add Amount
        </button>
      </div>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

and last but not the least, we have to import this store in the in the provider that we have to keep at the top most level, so as a parent of App.

so go to the index.js for your app and.

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import store from "./store/store";
import { Provider } from "react-redux";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);
Enter fullscreen mode Exit fullscreen mode

add this provider.

You can check this non-css redux-tut here.

Now seems easy af anyway, but lets have a look at the competitor, zustand, which has typescript support by the way.

Will start from the basics, lets create
npx create-react-app zustand-tut

and the dependicies
npm install zustand

yes thats right, thats all the dependicies we need.

now lets create a store. This time the folder structure is.

Zustand store folder structure

and now paste this in store/counterStore.js:

import create from "zustand";

export const useCounterStore = create((set) => ({
  count: 0,
  incrementBy1: () => set((state) => ({ count: state.count + 1 })),
  decrementBy1: () => set((state) => ({ count: state.count - 1 })),
  incrementByVal: (val) => set((state) => ({ count: state.count + val }))
}));
Enter fullscreen mode Exit fullscreen mode

and in counter.js, this:

import React, { useState } from "react";
import { useCounterStore } from "../store/counterStore";

export function Counter() {
  const { count, incrementBy1, decrementBy1, incrementByVal } = useCounterStore(
    (state) => state
  );
  const [incrementVal, setIncrementVal] = useState(5);

  const incrementByValHandler = (e) => {
    incrementByVal(Number(incrementVal));
  };
  return (
    <div>
      <div>
        <button aria-label="Increment value" onClick={incrementBy1}>
          +
        </button>
        <span>{count}</span>
        <button aria-label="Decrement value" onClick={decrementBy1}>
          -
        </button>
      </div>
      <div className>
        <input
          aria-label="Set increment amount"
          value={incrementVal}
          onChange={(e) => setIncrementVal(e.target.value)}
        />
        <button onClick={incrementByValHandler}>Add Amount</button>
      </div>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

And here we dont have to wrap it in provider as well.

and thats it. Lets try this on here.

Now as we can see, much less boilerplate, no dispatches, no providers, much more readable, and last but not least, much less code. Now 1 thing that is left is performance, for that I will write another article, in the mean time, if you wanna just trust my word, I like zustand more..

Thank you everyone.

Different type of state managers' articles coming soon.

yay zustaaand

Top comments (0)