Zustand is a very popular state management library for my friend, Daishi Kato. It is a lot more streamlined than Redux, but it follows that same Redux unidirectional model, which makes it very popular. Of course, it's a curse and blessing for me because I have to say
the word zustand all the time, and I think he just grabbed it from a grab bag of different words for the word state. Zustand in German means state. Okay, so what we're going to do
is we're going to take the 03 cart context with initial state example and create 07 complete zustand and then implement the whole example in zustand. Now, I recommend using two different
stores. Use that multi-store approach like we did with cart provider and with reviews provider. Use two different zustand state hooks to manage the state. Use one for the cart and then another for the reviews. If you have any questions about how to use zustand,
please look in the resources associated with this video. Good luck.
Zustand (German for "state") is a popular state management library created by Daishi Kato. It offers a more streamlined approach compared to Redux, while following the same unidirectional model for managing state.
For this exercise, we'll use Zustand to manage our application state. To get started, copy the 03-cart-context-with-initial-state directory and to a new 07-complete-zustand directory.
My recommendation is to use two different stores for managing the state.
Specifically, we'll use two different Zustand state hooks: one for managing the cart and another for reviews.
After installing zustand, you'll need to remove the existing CartContext and ReviewContext objects and replace them each with their own Zustand store.
In case you aren't familiar with Zustand, here's a quick overview of how it works.
WARNING You cannot safely use Zustand hooks that are declared globally!
Zustand hooks are normally global, but you can also create a Zustand hook and pass it around in a context, like so:
In order to get the Zustand hook in a Client Component, follow this pattern:
From there you can call the hook like this:
The above could also be shortened to:
Zustand also allows you to use selectors like so:
The above will force a re-render only when the returned value from the selector changes.
"use client";
import { useState, createContext, useContext } from "react";
import { create } from "zustand";
const createStore = (count: number) =>
create<{
count: number;
setCount: (cart: number) => void;
}>((set) => ({
count,
setCount(count: number) {
set({ count });
},
}));
const CountContext = createContext<ReturnType<typeof createStore> | null>(null);
export const useCount = () => {
if (!CartContext)
throw new Error("useCount must be used within a CountProvider");
return useContext(CountContext)!;
};
const CountProvider = ({
count,
children,
}: {
count: number;
children: React.ReactNode;
}) => {
const [store] = useState(() => createStore(count));
return (
<CountContext.Provider value={store}>{children}</CountContext.Provider>
);
};
export default CountProvider;
const useCountHook = useCount();
const { count, setCount } = useCountHook();
const { count, setCount } = useCount()(); // remove "Hook" and add another "()"
const count = useCount()((state) => state.count);