iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🚻

Basics of Using React.cache in Next.js App Router

に公開
  • Series posts
  1. https://zenn.dev/sora_kumo/articles/approuter-identification
  2. https://zenn.dev/sora_kumo/articles/approuter-cache
  3. https://zenn.dev/sora_kumo/articles/approuter-context

AppRouter and React.cache

In AppRouter, sharing data between Server Components that do not hold state is fundamentally based on React.cache. While fetch caching and Server Actions often draw a lot of attention in AppRouter discussions, this is a more foundational topic.

Starting to use fetch or Server Actions without knowing how to use React.cache is like trying to write code for external communication when you don't even know useState.

Simple Usage of React.cache

I will introduce how to use React.cache with a simple sample.

app/context.ts

cache caches functions. The value returned by the function does not necessarily have to be data. Just as the Context API sometimes uses a structure that returns a dispatch for data manipulation, you can write it in a similar way.

import { cache } from "react";

export const createContext = <T>(v: T) =>
  cache(() => {
    let value = v;
    return {
      set: (v: T) => (value = v),
      get: () => value,
    };
  });

export const context = createContext(0);

app/Test.tsx

context contains the return value of cache. To retrieve the cached instance, you need to call it as context(). While typical examples often show it taking arguments, it's not necessary if you don't need to switch instances using arguments as keys.

import { context } from "./context";

export const Test = () => {
  context().set(context().get() + 1);
  return <div>{context().get()}</div>;
};

app/page.tsx

import { Test } from "./Test";

const Page = () => {
  return (
    <>
      <Test />
      <Test />
      <Test />
      <Test />
    </>
  );
};

export default Page;

Execution Results

It might look like the values are just being incremented normally, but that is not actually the case. Even when you reload the page, the values remain 1 to 4. While this may seem expected, if you used module variables directly, the values would not be reset and would continue to increment even after reloads.

Explanation

React.cache creates an instance per component tree. In other words, when a new component tree is generated after a reload, a different memory space is created. Even if multiple requests reach the server at the same time, the values will not interfere with each other. By using this structure, you can share values across components, similar to the Context API.

Since this covers basic operations, I will write a separate article regarding the full-scale distribution of data from layout.tsx.

GitHubで編集を提案

Discussion