mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
I've added some tests to make sure the return value of `useRouter()` stays stable when we dispatch an action to the action queue. Honestly, i thought we had some, but it looks like we didn't. The motivation for this is that https://github.com/vercel/next.js/pull/76976 accidentally made `useRouter()` return a new value after each action (or navigation). This affected userspace code, which generally assumes that the return value of `useRouter` is stable (which it should be). --- The bug was here, in our `useReducer` (used for dispatching to the actionQueue): https://github.com/vercel/next.js/blob/5576edd3124277be568734d5d26923e9d75e520a/packages/next/src/client/components/use-reducer.ts#L45-L49 the `useCallback()` wrapping `dispatchCallback` also has `dispatchCallback` listed in the dependencies, and `dispatchCallback` is a fresh closure on every render, so in the end `useCallback` has no effect. as a result, the returned `dispatch` function is always changing, which leads to a cascade of changes everywhere. for example, we'll recreate `appRouter` each time `Router` rerenders (which mainly happens because of an action/navigation), because `dispatch` is one of its dependencies: https://github.com/vercel/next.js/blob/5b9d66a9b872ad28336988b768af34852a85e9e3/packages/next/src/client/components/app-router.tsx#L355-L356 Originally, i also had a fix for that here, but in the meantime, the bad memoization was fixed in https://github.com/vercel/next.js/pull/77354, so this is just tests now.
23 lines
717 B
JavaScript
23 lines
717 B
JavaScript
import { connection } from 'next/server'
|
|
import { NavigateAndTrackRouterIdentity } from '../navigate'
|
|
|
|
export default async function Page({ searchParams }) {
|
|
// the page should be dynamic so that `router.push()` to the current path actually does a request + navigates.
|
|
await connection()
|
|
const { count: countStr = '0' } = await searchParams
|
|
const count = Number.parseInt(countStr)
|
|
return (
|
|
<>
|
|
{/* add a changing element to know that we actually navigated */}
|
|
<div id="count-from-server">{count}</div>
|
|
<NavigateAndTrackRouterIdentity
|
|
href={
|
|
'/use-router/same-page' +
|
|
'?' +
|
|
new URLSearchParams({ count: count + 1 })
|
|
}
|
|
/>
|
|
</>
|
|
)
|
|
}
|