Using Client State Management Libraries

Pro Members Only

This lesson is available if you have an active subscription.

Alternatively, some member might be able to gift it to you.

If you already have a subscription, you can sign in.

Professional NextJS Lessons

1.Course Intro
free
⏱️ 2:05
2.Get Setup
free
⏱️ 2:05
3.Project Template
free
⏱️ 5:45
4.Introducing FullStack React
free
⏱️ 4:57
5.App Router Reference
free
⏱️ 7:08
6.NextJS Server vs. "use client" Rendering
⏱️ 5:01
7.Nesting Server and Client Components
⏱️ 8:51
8.Client Only Components
⏱️ 3:48
9.Global CSS in NextJS
⏱️ 6:30
10.CSS Modules and SASS
⏱️ 4:15
11.Tailwind CSS
⏱️ 5:17
12.NextJS Custom Fonts
⏱️ 4:08
13.Static vs Dynamic Rendering
⏱️ 4:55
14.NextJS Link Component
⏱️ 3:20
15.NextJS Link Prefetching
⏱️ 5:49
16.Navigation Scroll with Link
⏱️ 2:02
17.Replace Navigation History
⏱️ 1:35
18.NextJS Image Component
⏱️ 7:01
19.Dynamic Image URLs
⏱️ 5:34
20.Safe Colocation with Private Folders
⏱️ 2:12
21.NextJS Route Groups
⏱️ 3:07
22.Dynamic Routes
⏱️ 5:37
23.NextJS API Routes
⏱️ 6:03
24.NextRequest and NextResponse
⏱️ 2:41
25.Cookies in API Handlers
⏱️ 4:25
26.React Suspense Simplified
⏱️ 2:23
27.Power of Suspense Boundaries
⏱️ 3:52
28.use Promises
⏱️ 3:24
29.Stream Promise Results from Server to Client
⏱️ 3:03
30.use Requires a Cached Promise
free
⏱️ 2:30
31.Suspense Error Boundaries
⏱️ 4:42
32.React Server Functions
⏱️ 4:50
33.Server Actions for Powerful Forms
⏱️ 5:35
34.useActionState to Simplify Form Actions
⏱️ 6:38
35.React Serializable Types
⏱️ 2:42
36.Create Dynamic Images with NextJS ImageResponse
⏱️ 5:54
37.Deploy NextJS Application to Production
⏱️ 3:51
38.NextJS Environment Variables Masterclass
⏱️ 3:50
39.Deploying and Managing Environment Variables
⏱️ 4:38
40.Using Databases for Dynamic Server Side State
free
⏱️ 7:34
41.Mastering NextJS Layout Files
⏱️ 4:54
42.Client State Management with NextJS
⏱️ 3:48
43.Client State Management In Action
⏱️ 8:04
44.Using Client State Management Libraries
⏱️ 5:25
45.Detecting Server vs Client Runtime and useEffect
⏱️ 4:33
46.Demystifying ISR vs SSR vs SSG
⏱️ 3:07
47.Static Site Generation or SSG with NextJS
⏱️ 3:16
48.Incremental Static Regeneration (ISR) Simplified
⏱️ 2:51
49.API Routes Caching with NextJS
⏱️ 3:05
🚨 Work In Progress 🚧
Subscribe for Launch

Using Client State Management Libraries

Subscription Required

You must have an active subscription to access this content.
If you already have a subscription, you can sign in.

What is a State Management Library?

A state management library for React is nothing more than an instrument that provides better and more powerful abstractions when compared to react’s built in solution of useState.

This means that we can effectively replace any usage of useState with a state management library of our choice and reuse our existing patterns of sharing a state store across multiple pages of our NextJS app.

Practical Code Demo

You have a lot of choices in this space by I personally love Valtio which is a transparent reactive library. Transparent reactive means that we don’t need to put any effort to manually optimize which components should re-render on a particular state change.

In this lesson we migrate our previous shopping cart example from useState to Valtio! Final code demonstrated below.

lib/CartStoreContext.tsx
app/layout.tsx
lib/ui/Header.tsx
app/courses/page.tsx
app/courses/page.client.tsx
app/checkout/page.tsx
lib/types.ts
"use client";

import type { Course } from "./types";
import { createContext, PropsWithChildren, use } from "react";
import { proxy, useSnapshot } from "valtio";
import { proxyMap } from 'valtio/utils'

const useCreateCartStore = () => {
const state = proxy({
courses: proxyMap<string, Course>(),
});

/**
* Features to return:
* - array of courses in cart
* - ability to efficiently see if a course is in the cart
* - actions: add, remove, clear
*/
return {
useCoursesInCartArray: () => {
const snapshot = useSnapshot(state);
return [...snapshot.courses.values()];
},
useCoursesInCartMap: () => {
const snapshot = useSnapshot(state);
return snapshot.courses;
},
actions: {
addCourse: (toAdd: Course) => {
state.courses.set(toAdd.id, toAdd);
},
removeCourse: (toRemove: Course) => {
state.courses.delete(toRemove.id);
},
clearCart: () => {
state.courses.clear();
},
},
};
};

export type CartStore = ReturnType<typeof useCreateCartStore>;

const CartStoreContext = createContext<CartStore | null>(null);

export const CartStoreProvider = ({ children }: PropsWithChildren) => {
const cartStore = useCreateCartStore();
return (
<CartStoreContext.Provider value={cartStore}>
{children}
</CartStoreContext.Provider>
);
};

export const useCartStore = (): CartStore => {
const cartStore = use(CartStoreContext);
if (!cartStore) {
throw new Error("useCartStore must be used within a CartStoreProvider");
}
return cartStore;
};

Note that we didn't need to modify our Context sharing logic at all. We simply modified what our store returns and consumed the now API in our client components 🚀

javascript
typescript
react
playwright

Enjoy free content straight from your inbox 💌

No spam, unsubscribe at any time.

Transcript

00:00

State Management Library for React is nothing more than an instrument that provides better and more powerful abstractions when compared to Reacts built-in solution of U State. This means that we can effectively replace any usage of U State with a state management library of our choice and reuse our existing patterns of sharing the state store across multiple pages of our next JS app. For this demonstration, we will be using our shopping cart example that has two pages. It has a courses page where you can add and remove courses from the cart. And then we have the checkout page that displays the current courses that are present within that cart.

00:32

And this state is also shared with the header where we can see the count of the current courses within the cart. Let's migrate this example from U State to some popular state management library. You have a lot of choices in this space, but I personally love velho, which is a transparent, reactive library and transparent. Reactive means that we don't need to put in any effort to manually optimize which components should regenerate on a particular state change. It is free and open source, and we can install it from NPM by running NPMI velho. With this package installed, let's rewrite our shopping cart stored from scratch.

01:05

We no longer need use date because instead of that we will be using velho and specifically the two APIs proxy, which is used to create an observable and use snapshot, which we can call from components in order to read a value from that observable. Note that I also have a free detailed lesson on WELS ratio over on my YouTube, but you don't need to know too much about welche for this particular example, and we will explain things as we go along. The other API that we will need from welche is proxy map. Previously we were using E ES six map, but you cannot easily observe when that map is changed, which is why Welshire provides its own version fully

01:39

compatible with the native implementation without imports out of the way. Let's focus in on our store creator. We provide an initial state to the proxy method from welshire, and this allows Welshire to transparency observe if any property on this particular object changes in terms of features required of our store for our application. Let's list down the key things that we require. We need the ability to get the list of courses in the cart as an array, we should be able to efficiently query if a particular course is in the cart. And finally, we need the actions to add a course, remove a course, or clear the cart completely from a store creator, we will return an object

02:13

that meets these objectives. First up, we create a hook that allows you to get the items in the cart as an array. The reason why this is a hook is because Welche gives us a used snapshot, which essentially allows welche to track which component is rendering the current hook, and therefore the values that this component reads will cause WELCHE to trigger a re-render for that component. Next up, in order to efficiently query if a particular course is present within the cart, we create another hook which simply returns the courses map so that the consumer can use the HAS method, which is present on proxy map just like it is present

02:45

on E ES six map. Finally, for the actions, we create a new sub object. The first action is add course, and here you can see how simple welche makes our life. In order to add a new item, we simply invoke the native set method. No need to immutably Create a new array while she will automatically track the changes and cause the necessary reads. And this will actually perform better than us creating a new map again and again. The same is true for remove course section. We simply delete the key from the courses map. And finally, for clear cut, we simply invoke map clear and this object that we are returning meets all the requirements that we have for the state of our application.

03:19

Since the contract provided by our store has changed, of course we are going to have to modify the code that consumes the store. Fortunately, all those places will be highlighted for us by TypeScript. Let's run a simple TypeScript build to see all the errors. TypeScript has identified seven places that we need to look at, so let's jump in and make the edits. The first one is in the header where we were getting an array of items in the cart. And for this we have a new method called use courses in cart array. With this change, this file is good to go. There are three errors within the courses page, and our objective is to fix this file so that it is no longer showing red in color.

03:52

For the first one, we are trying to see if a particular course is within the cart. And for this very use case, we exposed a method that allows us to get access to the underlying map so we can quickly check if a course with a particular ID is present within the cart. So we get the map in the root of the component because it is a hook and hooks need to be at the root of the react component. And once we have that map within the loop, we simply use, its has method and pass in the course id. The other two errors are simply related to the fact that we decided to move the actions into the actions property to make our code a bit neater. With these modifications,

04:23

this file is no longer showing red. Finally, we have a few errors within the checkout page. The first one is related to the fact that we need to use a hook in order to get access to the cart array. We make that modification and that error is fixed. And the second one is related to the fact that we moved our actions into the actions property. We make that modification and this file is also good to go. And now for the moment of truths, does our application behave the same way as it did before? So let's boot it up and play around with it. We add a few items to the cart and you can see that the action buttons are swapping from add to remove and the count is updating in the NAV as well.

04:58

And if you go to the checkout page, we can see the three courses that we added. And if we choose to clear the cart, you can see that those courses are gone and the count is updated in the header as well. Note that for all of this, our core infrastructure of creating a store and sharing it across different pages remained exactly the same. The only modifications that were done were in the store. We modified the store from U State to a library, and therefore when we consumed the store, we had to use the API that was specific to this state management library.

Professional NextJS

Professional NextJS

1.Course Intro
free
⏱️ 2:05
2.Get Setup
free
⏱️ 2:05
3.Project Template
free
⏱️ 5:45
4.Introducing FullStack React
free
⏱️ 4:57
5.App Router Reference
free
⏱️ 7:08
6.NextJS Server vs. "use client" Rendering
⏱️ 5:01
7.Nesting Server and Client Components
⏱️ 8:51
8.Client Only Components
⏱️ 3:48
9.Global CSS in NextJS
⏱️ 6:30
10.CSS Modules and SASS
⏱️ 4:15
11.Tailwind CSS
⏱️ 5:17
12.NextJS Custom Fonts
⏱️ 4:08
13.Static vs Dynamic Rendering
⏱️ 4:55
14.NextJS Link Component
⏱️ 3:20
15.NextJS Link Prefetching
⏱️ 5:49
16.Navigation Scroll with Link
⏱️ 2:02
17.Replace Navigation History
⏱️ 1:35
18.NextJS Image Component
⏱️ 7:01
19.Dynamic Image URLs
⏱️ 5:34
20.Safe Colocation with Private Folders
⏱️ 2:12
21.NextJS Route Groups
⏱️ 3:07
22.Dynamic Routes
⏱️ 5:37
23.NextJS API Routes
⏱️ 6:03
24.NextRequest and NextResponse
⏱️ 2:41
25.Cookies in API Handlers
⏱️ 4:25
26.React Suspense Simplified
⏱️ 2:23
27.Power of Suspense Boundaries
⏱️ 3:52
28.use Promises
⏱️ 3:24
29.Stream Promise Results from Server to Client
⏱️ 3:03
30.use Requires a Cached Promise
free
⏱️ 2:30
31.Suspense Error Boundaries
⏱️ 4:42
32.React Server Functions
⏱️ 4:50
33.Server Actions for Powerful Forms
⏱️ 5:35
34.useActionState to Simplify Form Actions
⏱️ 6:38
35.React Serializable Types
⏱️ 2:42
36.Create Dynamic Images with NextJS ImageResponse
⏱️ 5:54
37.Deploy NextJS Application to Production
⏱️ 3:51
38.NextJS Environment Variables Masterclass
⏱️ 3:50
39.Deploying and Managing Environment Variables
⏱️ 4:38
40.Using Databases for Dynamic Server Side State
free
⏱️ 7:34
41.Mastering NextJS Layout Files
⏱️ 4:54
42.Client State Management with NextJS
⏱️ 3:48
43.Client State Management In Action
⏱️ 8:04
44.Using Client State Management Libraries
⏱️ 5:25
45.Detecting Server vs Client Runtime and useEffect
⏱️ 4:33
46.Demystifying ISR vs SSR vs SSG
⏱️ 3:07
47.Static Site Generation or SSG with NextJS
⏱️ 3:16
48.Incremental Static Regeneration (ISR) Simplified
⏱️ 2:51
49.API Routes Caching with NextJS
⏱️ 3:05
🚨 Work In Progress 🚧
Subscribe for Launch