vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.52k stars 26.92k forks source link

Requests not memoized when using cookies #54745

Open lorenzosim opened 1 year ago

lorenzosim commented 1 year ago

Verify canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.4.0: Mon Mar  6 21:00:41 PST 2023; root:xnu-8796.101.5~3/RELEASE_ARM64_T8103
    Binaries:
      Node: 18.16.1
      npm: 9.5.1
      Yarn: 1.22.19
      pnpm: N/A
    Relevant Packages:
      next: 13.4.20-canary.12
      eslint-config-next: 13.4.10
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.1.6
    Next.js Config:
      output: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

App Router

Link to the code that reproduces this issue or a replay of the bug

https://codesandbox.io/p/sandbox/fervent-hugle-mcfppg

To Reproduce

Sample page that calls /foo twice on each load, request is not memoized:

import { cookies } from 'next/dist/client/components/headers';
import { Metadata } from 'next/types'

async function fetchName() {
    cookies();
    const res = await fetch('http://localhost:3000/foo',)
    const repo = await res.json();
    return repo.name;
}   

export async function generateMetadata(): Promise<Metadata> {
    const name = await fetchName();
    return { title: name}
  }

export default async function page() {
    const name = await fetchName();
    return <p>{name}</p>;
}

Describe the Bug

When using cookies, requests are not memoized. This is particuarly important for the example above: for a logged in user (hence the cookies), we need to show some data in both the title and the page.

In the pages router the above is as simple as the following and that obviously sends only 1 requests:

export async function getServerSideProps() {
    const res = await fetch('localhost:3000')
    const repo = await res.json();
    return { props: { name: repo.name } }
}
export default function page({name}) {
    return <><Head><title>{name}</title></Head><p>{name}</p></>;
}

Expected Behavior

Requests should be memoized.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

zwarunek commented 1 year ago

I believe that this could be linked with this issue here #52126. This is a pretty big issue, would appreciate some investigation.

yanghuilong commented 1 year ago

https://nextjs.org/docs/app/building-your-application/caching#dynamic-functions

lorenzosim commented 1 year ago

Dynamic rendering with cookies is fine, but what I'm talking about here is multiple fetch calls within the same request. Likely the issue is what @zwarunek linked to.