Skip to content

Commit 9cc216b

Browse files
test(react-router): add more variants to store-updates test (#5019)
Add a few more setup configurations to measure the number of `__store` updates: - with caching (`staleTime > 0`) - when preloading multiple times the same route (simulates hovering a list of links to the same page w/ different params) --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 40f9ab7 commit 9cc216b

File tree

1 file changed

+87
-7
lines changed

1 file changed

+87
-7
lines changed

packages/react-router/tests/store-updates-during-navigation.test.tsx

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ function setup({
3131
scripts,
3232
defaultPendingMs,
3333
defaultPendingMinMs,
34+
staleTime,
3435
}: {
3536
beforeLoad?: () => any
3637
loader?: () => any
@@ -39,24 +40,26 @@ function setup({
3940
scripts?: () => any
4041
defaultPendingMs?: number
4142
defaultPendingMinMs?: number
43+
staleTime?: number
4244
}) {
4345
const select = vi.fn()
4446

4547
const rootRoute = createRootRoute({
4648
component: function RootComponent() {
4749
useRouterState({ select })
48-
return <Outlet />
50+
return (
51+
<>
52+
<Link to="/">Back</Link>
53+
<Link to="/posts">Posts</Link>
54+
<Outlet />
55+
</>
56+
)
4957
},
5058
})
5159
const indexRoute = createRoute({
5260
getParentRoute: () => rootRoute,
5361
path: '/',
54-
component: () => (
55-
<>
56-
<h1>Index</h1>
57-
<Link to="/posts">Posts</Link>
58-
</>
59-
),
62+
component: () => <h1>Index</h1>,
6063
})
6164

6265
const postsRoute = createRoute({
@@ -83,13 +86,24 @@ function setup({
8386
defaultPendingComponent: () => <p>Loading...</p>,
8487
defaultNotFoundComponent: () => <h1>Not Found Title</h1>,
8588
defaultPreload: 'intent',
89+
defaultStaleTime: staleTime,
90+
defaultGcTime: staleTime,
8691
})
8792

8893
render(<RouterProvider router={router} />)
8994

9095
return { select, router }
9196
}
9297

98+
async function back() {
99+
const link = await waitFor(() => screen.getByRole('link', { name: 'Back' }))
100+
fireEvent.click(link)
101+
const title = await waitFor(() =>
102+
screen.getByRole('heading', { name: /Index/ }),
103+
)
104+
expect(title).toBeInTheDocument()
105+
}
106+
93107
async function run({ select }: ReturnType<typeof setup>) {
94108
// navigate to /posts
95109
const link = await waitFor(() => screen.getByRole('link', { name: 'Posts' }))
@@ -211,4 +225,70 @@ describe("Store doesn't update *too many* times during navigation", () => {
211225
// Any change that increases this number should be investigated.
212226
expect(updates).toBe(14)
213227
})
228+
229+
test('navigate, w/ preloaded & async loaders', async () => {
230+
const params = setup({
231+
beforeLoad: () => Promise.resolve({ foo: 'bar' }),
232+
loader: () => resolveAfter(100, { hello: 'world' }),
233+
staleTime: 1000,
234+
})
235+
236+
await params.router.preloadRoute({ to: '/posts' })
237+
const updates = await run(params)
238+
239+
// This number should be as small as possible to minimize the amount of work
240+
// that needs to be done during a navigation.
241+
// Any change that increases this number should be investigated.
242+
expect(updates).toBe(7)
243+
})
244+
245+
test('navigate, w/ preloaded & sync loaders', async () => {
246+
const params = setup({
247+
beforeLoad: () => ({ foo: 'bar' }),
248+
loader: () => ({ hello: 'world' }),
249+
staleTime: 1000,
250+
})
251+
252+
await params.router.preloadRoute({ to: '/posts' })
253+
const updates = await run(params)
254+
255+
// This number should be as small as possible to minimize the amount of work
256+
// that needs to be done during a navigation.
257+
// Any change that increases this number should be investigated.
258+
expect(updates).toBe(6)
259+
})
260+
261+
test('navigate, w/ previous navigation & async loader', async () => {
262+
const params = setup({
263+
loader: () => resolveAfter(100, { hello: 'world' }),
264+
staleTime: 1000,
265+
})
266+
267+
await run(params)
268+
await back()
269+
const updates = await run(params)
270+
271+
// This number should be as small as possible to minimize the amount of work
272+
// that needs to be done during a navigation.
273+
// Any change that increases this number should be investigated.
274+
expect(updates).toBe(5)
275+
})
276+
277+
test('preload a preloaded route w/ async loader', async () => {
278+
const params = setup({
279+
loader: () => resolveAfter(100, { hello: 'world' }),
280+
})
281+
282+
await params.router.preloadRoute({ to: '/posts' })
283+
await new Promise((r) => setTimeout(r, 20))
284+
const before = params.select.mock.calls.length
285+
await params.router.preloadRoute({ to: '/posts' })
286+
const after = params.select.mock.calls.length
287+
const updates = after - before
288+
289+
// This number should be as small as possible to minimize the amount of work
290+
// that needs to be done during a navigation.
291+
// Any change that increases this number should be investigated.
292+
expect(updates).toBe(1)
293+
})
214294
})

0 commit comments

Comments
 (0)