ProNextJS
    lesson

    Intro to State Management with Next.JS App Router

    Jack HerringtonJack Herrington

    For years, Redux has been synonymous with "state management" for React & Next.JS apps. You put all your data in your Redux store and you use it in any component, in any place, both on a server and on the client.

    But with the introduction of the Next.js App Router, the tables have been flipped on us.

    We now have two different types of components: React Server Components (RSCs for short) that only render on the server, and Client Components that render both on the client and on the server.

    To make matters even more complicated, the App Router can now render asynchronously, which means that a single server could potentially handle more than one request at a time.

    This brings us to some new rules of state management in a Next.JS app.

    Rule #1: No Global Stores.

    The first rule of state management with Next.JS App Router is to avoid using a global store.

    Up until now, we've become used to simply defining a store as a global variable, which is really easy.

    But because App Router can handle multiple requests simultaneously, there's potential for data being handled from two different requests at the same time. This could lead to one customer getting data meant to be returned from another customer's request.

    Obviously, this would be bad.

    Throughout this tutorial you'll learn how to approach having a store for your application state without creating a global variable, which would avoid this problem.

    Rule #2: RSCs Should Not Show the Store's Data

    The second rule of state management in an App Router app is that React Server Components should not show data from the store.

    This rule is easy to enforce when following the first rule, because it's hard for an RSC to get access to the data in the store when the store hasn't been defined globally.

    But what data should be shown? That's defined by rule number three.

    Rule #3: RSCs Show Immutable Data, while Client Components Show Mutable

    The type of component used to display data determines on the type of data you're working with.

    Immutable data are the types of data that don't change during your session with the page, while mutable data can change on the client.

    We'll be using a simple e-commerce application for this tutorial that will display both kinds of data.

    Examples of immutable data include the list of products and their descriptions and prices for each product. These will be handled by React Server Components.

    Client Components will be used for the mutable data that can change on the client. Examples here would be the cart and product reviews.

    Rock-Solid State Management Patterns

    This tutorial is all about how to manage mutable data no matter what state management system you use. We'll look at examples with React Hooks and Context, as well as global management systems like Redux, Zustand, and Jotai.

    By the end of this tutorial, you'll have hands-on practice implementing rock-solid patterns for managing mutable state on a client.

    In the next section, we'll start with a dive into implementing a shopping cart using React Context and Hooks.

    Transcript

    When it comes to state management, Redux has been synonymous with React for years. If you needed state management in your application, you used Redux. And that applied to Next.js as well. You put all your data in your Redux store and you use it in any component, in any place, both on a server and on the client.

    But now with the app router, they have flipped the tables on us. Now we have two different types of components. We have the React server components, or RSCs, that only render on the server. And then we've got the client components that render both on the client and on the server.

    And to make matters even more complicated, the app router can now render asynchronously, which means that potentially a single server can handle more than one request at a time, which leads us to rule number one, which is no global stores. We're used to simply defining a store as a global variable, which is really easy.

    But now the app router can potentially handle multiple requests simultaneously, which means that if you put all your data in the store, you could potentially have data from two different requests at the same time. So customer one, because the customers choose data, and that's not great.

    So how do we manage a store, like a Redux store, without declaring as a global variable? Well, you're going to learn that and much more as we go through this tutorial. Now our second rule relates to our first rule. And our second rule is that RSCs shouldn't show data from the store,

    which is pretty easy to enforce because it's hard for an RSC to get access to the data in the store when the store isn't defined globally. And that's kind of a clue that we shouldn't be showing that kind of data in the first place.

    In fact, rule number three is that RSCs should show immutable data and client components should show mutable data. So what am I talking about here? So immutable data are the types of data that don't change during your session with the page.

    Mutable data are things that can change on the client. Throughout this tutorial, we're going to use a simple e-commerce application that has some immutable data, like the list of products, as well as a description and the price for each product, and then some mutable data, which is going to be changing on the client, like the cart, as well as the product reviews.

    So this tutorial is all about how to manage that mutable data using either React Hooks and Context or a global management system like Redux, Sushdand, or Jotai. And at the end of this tutorial, you will have rock-solid patterns for how to manage mutable state on a client.

    Now let's start out by implementing our cart using React Context and Hooks.