How to Setup Zustand in Next.js

Last Updated Date: 12-06-2023

This note outlines how to setup Zustand in Next.js. Which is an alternative react state management solution of Redux and MobX.

Please notice that:

  • Page Router will be used instead of the new App Router introduced in Next.js 13.

  • TypeScript will be used instead of JavaScript for better type declaration.

Introduction of Zustand

Zustand is a tool for managing data in React apps. It facilitates the storage, modification, and utilization of data across different app components. It is user-friendly and requires minimal code, making it accessible and easy to work with.

Initialize the Project

First of all, initialize a Next.js application and install the dependencies first.

# npm
npx create-next-app

# pnpm
pnpm create next-app

After creating the project, install the zustand dependency into it.

# npm
npm install zustand

# pnpm
pnpm add zustand

Setup Zustand

After the initialization, create a directory named context within the src directory (alternative methods for the code are also welcome), then create a file for the state management code. For example: src/context/example.tsx.

Then import zustand into the code:

import { create } from "zustand";

After the importation, add the type for it as follows:

// type declaration
type ExampleContext = {
    // boolean state
    booleanState: boolean;
    // function to set boolean state to true
    on: () => void;
    // function to set boolean state to false
    off: () => void;
    // string state
    stringState: string;
    // function set string state with "val" variable
    setString: (val: string) => void;
};

Then add the funcition to initial and interract with the Zustand state management.

const useExampleContext = create<ExampleContext>((set) => ({
    // the initial value was set to false here
    booleanState: false,
    on: () => {
        // setter function
        set({ booleanState: true });
    },
    off: () => {
        // setter function
        set({ booleanState: true });
    },
    // initual value was set to ""
    stringState: "",
    // will require a "val" and used for setter function
    setString: (val) => {
        set({ stringState: val });
    },
}));

After all, the code should be look like this:

import { create } from "zustand";

type ExampleContext = {
    booleanState: boolean;
    on: () => void;
    off: () => void;
    stringState: string;
    setString: (val: string) => void;
};

const useExampleContext = create<ExampleContext>((set) => ({
    booleanState: false,
    on: () => {
        set({ booleanState: true });
    },
    off: () => {
        set({ booleanState: true });
    },
    stringState: "",
    setString: (val) => {
        set({ stringState: val });
    },
}));

// don't forget to export it
export default useExampleStore;

Use Zustand

After the setup, the exmaple context can be used somewhere else.

import useExampleStore from "@/context/example";

const blste = useExampleStore((s) => s.booleanState);
const on = useExampleStore((s) => s.on);
const off = useExampleStore((s) => s.off);
const strste = useExampleStore((s) => s.stringState);
const setStr = useExampleStore((s) => s.setString);

// ...

setStr("bruh");

Conclusion

The example provided is just a basic introduction of Zustand, You may discover more features of it as your application grows. Feel free to contact if there are any problem in this note.