ProNextJS
    exercise

    The Atomic Model of State Management with Jotai

    Jack HerringtonJack Herrington

    Jotai: An Atomic Model State Management Library

    Jotai is a state management library that is built on the Atomic Model for state management, and is a bit exotic when compared to the other state managers we've seen over the past decade with React.

    Introducing the Atomic Model

    In the atomic model, atoms represent distinct pieces of state that can be directly mutated.

    For our ecommerce example, we would have atoms for cart and reviews.

    Then for an average rating atom, we would have it depend on the reviews atom to make its calculation.

    Think of the atomic model as being similar to a spreadsheet where cells interact through equations: when one cell changes, the others update automatically, eliminating the need for dependency arrays or manual recalculations.

    Using Jotai to Create Atoms

    Intially Jotai atoms were defined globally, but now we are able to create a store and provide it using a store provider.

    Each store can have instances of particular atoms, and there can either be multiple stores throughout the hierarchy or a single store at the top of the hierarchy.

    For this exercise, we'll use the single store approach. We will have the provider at the top of the layout and the atoms will go down the tree.

    Challenge

    The objective of this exercise is to remove the existing React cart context and replace it completely with Jotai.

    To do this, you'll need to remove the existing CartContext object and replace it with a Jotai store. Then use atoms to model the cart and reviews.

    As before, you cannot safely use a Jotai atoms declared globally!

    After you add jotai to the project, you'll be ready to create the atoms.

    Here's an example of how to create an atom:

    import { atom } from "jotai";
    export const countAtom = atom<number>(0);
    

    You can create a Jotai "store" for atoms using createStore. Here is an example provider that uses Jotai's Provider to pass the store around:

    "use client";
    import { useState } from "react";
    import { createStore, Provider } from "jotai";
    const StoreProvider = ({ children }: { children: React.ReactNode }) => {
    	const [store] = useState(() => createStore());
    	return <Provider store={store}>{children}</Provider>;
    };
    
    export default StoreProvider;
    

    Then in client components, you can access the atoms using useAtom and useAtomValue, and get the current atom store using useStore.

    To access the value of the count atom in the store you would use:

    const countValue = useAtomValue(countAtom, {
    	store: useStore(),
    });
    

    Note that if you leave off the useStore, your code will be using the global atom value which you shouldn't use with the App Router.

    As one last hint, watch out for how to safely initialize the reviews atom on route changes between detail pages. Remember, the Jotai store is global to the layout and contains the reviews as well as the cart.

    Transcript

    Jotai is a state management library that is built on the Atomic model. I think it's fair to say that the Atomic model is a little bit exotic in terms of the normal state management models that we've seen for the past decade as we've been working with React, and the fact that React didn't have good state management built-in,

    has created a flourishing of state managers, and so the Atomic model has come along recently as a new wave of state managers, including Recoil, which is from Meta, and Jotai from our friend Daishi Kato. Now, what makes Jotai unique is all of

    the plugins and all of the extra stuff that you can add onto Jotai. That's how it distinguishes itself from Recoil. Now, if you're like, what is Atomic model in the first place? Well, Atomic model is an interesting way of managing state. So every piece of state is an atom,

    and then you can mutate atoms directly. So we would have a cart atom, we would have a reviews atom, and then for example, if we wanted to have an average rating reviews atom, that could depend on the reviews atom and calculate that value.

    So it's really neat. I liken it to cells in a spreadsheet, and so when you've got cells and those cells in the spreadsheet reference each other in equations, then when you make a change, everything updates. That's how the Atomic model works, and that's really nice.

    So no more dependency arrays or any of that. It automatically calculates all those dependencies for you. Now, initially at Jotai, you would define atoms globally, just as global variables, and you would set and get them globally. Now, you can actually create a store and provide it using a store provider,

    and those stores can have instances of those particular atoms. For example, the cart atom and the reviews atom, and they exist within that store, and you can have multiple stores throughout the hierarchy, or you have one store top of the hierarchy like we're going to do in this one. With the layout, we're going to put the store provider

    there and then our atoms all the way down the tree. Again, this is the single store approach. So you're going to make sure that as you initialize those atoms, you're doing it the right way when it comes to reviews. So as you click along between the various product routes, you set those atoms correctly.

    So the objective of this exercise is to remove the existing React cart context and replace it completely with Jotai for the cart as well as the reviews. If you have any questions, be sure to look in the resources section. Good luck.