Skip to content

Commit

Permalink
Fix fetch caching inside of "use cache"
Browse files Browse the repository at this point in the history
Follow-up to #71754:

> This ensures if you have a `fetch` with `cache: 'no-store'` inside of
> `use cache`/`unstable_cache` we don't update the revalidate period to
> `0` which effectively makes the `use cache` a no-op. This doesn't
> change the behavior if `revalidate: 0` is defined on a `fetch` inside
> of `use cache` as that is more explicitly changing the revalidate
> period similar to `cacheLife()`.

This PR follows this logic and ensures that we also cache fetches inside
of `"use cache"` if `cache: 'no-store'` is not specified.

It also adds a test to ensure that `revalidate: 0` inside of `"use
cache"` is still considered.
  • Loading branch information
unstubbable committed Oct 24, 2024
1 parent eabfdea commit 6eaa67d
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
8 changes: 6 additions & 2 deletions packages/next/src/server/lib/patch-fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,15 @@ export function createPatchedFetcher(
? []
: workUnitStore.implicitTags

// Inside unstable-cache we treat it the same as force-no-store on the page.
// Inside unstable-cache or "use cache", we treat it the same as
// force-no-store on the page.
const pageFetchCacheMode =
workUnitStore && workUnitStore.type === 'unstable-cache'
workUnitStore &&
(workUnitStore.type === 'unstable-cache' ||
workUnitStore.type === 'cache')
? 'force-no-store'
: workStore.fetchCache

const isUsingNoStore = !!workStore.isUnstableNoStore

let currentFetchCacheConfig = getRequestMeta('cache')
Expand Down
18 changes: 18 additions & 0 deletions test/e2e/app-dir/use-cache/app/cache-fetch/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'

async function getData() {
'use cache'

return fetch('https://next-data-api-endpoint.vercel.app/api/random').then(
(res) => res.text()
)
}

export default async function Page() {
return (
<>
<p>index page</p>
<p id="random">{await getData()}</p>
</>
)
}
18 changes: 18 additions & 0 deletions test/e2e/app-dir/use-cache/app/fetch-revalidate/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'

async function getData() {
'use cache'

return fetch('https://next-data-api-endpoint.vercel.app/api/random', {
next: { revalidate: 0 },
}).then((res) => res.text())
}

export default async function Page() {
return (
<>
<p>index page</p>
<p id="random">{await getData()}</p>
</>
)
}
18 changes: 18 additions & 0 deletions test/e2e/app-dir/use-cache/use-cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,15 @@ describe('use-cache', () => {
// expect(time4).toBe(time3);
})

it('should cache fetch without no-store', async () => {
const browser = await next.browser('/cache-fetch')

const initialValue = await browser.elementByCss('#random').text()
await browser.refresh()

expect(await browser.elementByCss('#random').text()).toBe(initialValue)
})

it('should override fetch with no-store in use cache properly', async () => {
const browser = await next.browser('/cache-fetch-no-store')

Expand All @@ -275,4 +284,13 @@ describe('use-cache', () => {

expect(await browser.elementByCss('#random').text()).toBe(initialValue)
})

it('should use revalidate config in fetch', async () => {
const browser = await next.browser('/fetch-revalidate')

const initialValue = await browser.elementByCss('#random').text()
await browser.refresh()

expect(await browser.elementByCss('#random').text()).not.toBe(initialValue)
})
})

0 comments on commit 6eaa67d

Please sign in to comment.