|
1 | 1 | import React from 'react' |
2 | 2 |
|
3 | | -export function TestReactCache() { |
4 | | - return ( |
5 | | - <> |
6 | | - <TestReactCacheFn /> |
7 | | - <TestReactCacheComponent /> |
8 | | - </> |
9 | | - ) |
10 | | -} |
11 | | - |
12 | | -// Use module-level state but reset it for clean tests |
13 | | -function resetCounters() { |
14 | | - actionCount = 0 |
15 | | - cacheFnCount = 0 |
16 | | -} |
| 3 | +export async function TestReactCache(props: { url: URL }) { |
| 4 | + if (props.url.searchParams.has('test-react-cache')) { |
| 5 | + await Promise.all([ |
| 6 | + testCacheFn('test1'), |
| 7 | + testCacheFn('test2'), |
| 8 | + testCacheFn('test1'), |
| 9 | + testNonCacheFn('test1'), |
| 10 | + testNonCacheFn('test2'), |
| 11 | + testNonCacheFn('test1'), |
| 12 | + ]) |
| 13 | + } else { |
| 14 | + cacheFnCount = 0 |
| 15 | + nonCacheFnCount = 0 |
| 16 | + } |
17 | 17 |
|
18 | | -function TestReactCacheFn() { |
19 | 18 | return ( |
20 | | - <form |
21 | | - data-testid="test-react-cache-fn" |
22 | | - action={async (formData) => { |
23 | | - 'use server' |
24 | | - const reset = formData.get('reset') |
25 | | - if (reset === 'true') { |
26 | | - resetCounters() |
27 | | - return |
28 | | - } |
29 | | - actionCount++ |
30 | | - const argument = formData.get('argument') || 'default' |
31 | | - await testCacheFn(argument) |
32 | | - }} |
33 | | - > |
34 | | - <button>test-react-cache-fn</button> |
35 | | - <input className="w-25" name="argument" placeholder="argument" /> |
36 | | - <input type="hidden" name="reset" value="false" /> |
37 | | - <span> |
38 | | - (actionCount: {actionCount}, cacheFnCount: {cacheFnCount}) |
| 19 | + <div data-testid="test-react-cache"> |
| 20 | + <a href="?test-react-cache">test-react-cache</a>{' '} |
| 21 | + <span data-testid="test-react-cache-result"> |
| 22 | + (cacheFnCount = {cacheFnCount}, nonCacheFnCount = {nonCacheFnCount}) |
39 | 23 | </span> |
40 | | - </form> |
| 24 | + </div> |
41 | 25 | ) |
42 | 26 | } |
43 | 27 |
|
44 | | -let actionCount = 0 |
45 | 28 | let cacheFnCount = 0 |
| 29 | +let nonCacheFnCount = 0 |
46 | 30 |
|
47 | | -const testCacheFn = React.cache(async (arg: unknown) => { |
| 31 | +const testCacheFn = React.cache(async (...args: unknown[]) => { |
| 32 | + console.log('[cached:args]', args) |
48 | 33 | cacheFnCount++ |
49 | | - // Simulate async work |
50 | 34 | await new Promise((resolve) => setTimeout(resolve, 20)) |
51 | | - return arg |
52 | 35 | }) |
53 | 36 |
|
54 | | -function TestReactCacheComponent() { |
55 | | - // Similar to the external reference, create a simple demonstration |
56 | | - const timestamp = new Date().toISOString() |
57 | | - |
58 | | - return ( |
59 | | - <div data-testid="test-react-cache-component"> |
60 | | - <div data-testid="test-react-cache-basic"> |
61 | | - React.cache basic test: {timestamp} |
62 | | - </div> |
63 | | - <React.Suspense fallback={<div>Loading...</div>}> |
64 | | - <TestReactCacheAsyncInner /> |
65 | | - </React.Suspense> |
66 | | - </div> |
67 | | - ) |
68 | | -} |
69 | | - |
70 | | -async function TestReactCacheAsyncInner() { |
71 | | - // Call cached function - in server components React.cache should work within the same request |
72 | | - await testCacheFn('constant-arg') |
73 | | - await testCacheFn('constant-arg') // Should use cache |
74 | | - |
75 | | - return ( |
76 | | - <div data-testid="test-react-cache-async-inner"> |
77 | | - Async inner: cacheFnCount = {cacheFnCount} |
78 | | - </div> |
79 | | - ) |
| 37 | +const testNonCacheFn = async (...args: unknown[]) => { |
| 38 | + console.log('[not-cached:args]', args) |
| 39 | + nonCacheFnCount++ |
| 40 | + await new Promise((resolve) => setTimeout(resolve, 20)) |
80 | 41 | } |
0 commit comments