Keep request data local

Module scope is shared by every request; pass user data down as props.

From vercel-react-best-practices, rule server-no-shared-module-state.

Two users, one module

Send both requests. Then change how far apart they arrive.

Module-level variableBad
module scopelet currentUser = null
    currentUser = await auth()
    Passed as a propGood
    module scope// no request data
      <Dashboard user={user} />

      export default async function Page() {
        const user = await auth()
        return <Dashboard user={user} />
      }
      
      function Dashboard({ user }: { user: User | null }) {
        return <div>{user?.name}</div>
      }

      Under real traffic

      Fire a burst from four users. Each tile is one response.

      Module-level variableBad

        0 showed another user

        let currentUser
        Passed as a propGood

          0 showed another user

          const user = await auth()

          Why it matters, pros and cons

          Why it matters

          Renders run concurrently in one process. A module variable is shared by all of them.

          Pros

          • No response can show another user's data.
          • No race that only shows up under load.
          • Data flow is visible in props.

          Cons

          • Deep trees need props or React.cache().
          • Immutable config at module scope is fine.
          • So are caches keyed per request or user.