Zustand and Next.js

Zustand and Next.js

As your application grows, it helps to be more intentional about how your state is organized and how the data flows between your components.

Zustand is a small, fast, and scalable bearbones state management solution. Zustand has a comfy API based on hooks. It isn't boilerplatey or opinionated but has enough convention to be explicit and flux-like.
There is a comparison between Zustand and other libraries that you can find here.

Let's go and config Zustand in a Next.js app:

Steps:

  1. Create Next app

  2. Install Zustand

  3. Create a store and use

  4. Run dev server

1- Create Next.js project:

npx create-next-app@latest

yarn create next-app

pnpm create next-app

you will then be asked some questions, answer them to finish the creating project.

2- Install Zustand

npm i zustand

yarn add zustand

pnpm add zustand

3- Create store

Create a directory into src called stores and also create a file theme-store.ts :

// src/stores/theme-store.ts
import {create} from 'zustand';

interface ThemeState {
    mode: "light" | "dark",
    changeMode: () => void
}

const useThemeState = create<ThemeState>()((set) => ({
    mode: "light",
    changeMode: () => set((state) => ({
        mode: state.mode === 'light' ? 'dark' : 'light'
    })),
}))

export default useThemeState;
  • Your store is a hook.

  • You can put anything in it: primitives, objects, functions.

  • The set function merges state.

Now, let's create a button to toggle themes:

// src/app/page.tsx

"use client"
// project imports
import styles from './page.module.css'
import useThemeState from "@/stores/theme-store";

export default function Home() {
    const {mode,changeMode} = useThemeState(state=>state);
    return (
        <main className={styles.main}>
                <button onClick={changeMode}>Toggle Theme</button>
                <div>{mode}</div>
        </main>
    )
}

If you press the button you can see the state will update:

We could pass the state to each component we want:

// src/app/ComponentA.tsx

import useThemeState from "@/stores/theme-store";

export default function ComponentA(){
    const mode = useThemeState(state=>state.mode);

    const darkStyles = {
        width:200,
        height:200,
        backgroundColor:'black',
        color:'white'
    }

    const lightStyles = {
        width:200,
        height:200,
        backgroundColor:'lightgray',
    }

    return(
        <div style={mode === 'light' ? darkStyles : lightStyles}>
            <div>{mode} Mode</div>
        </div>
    )
}

Done! And thenk you for your time. Enjoy coding..

Source code: https://github.com/hamitmohamadi/zustand-and-next