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.
17 lines
506 B
JavaScript
17 lines
506 B
JavaScript
'use client'
|
|
import { usePathname } from 'next/navigation'
|
|
import { NavigateAndTrackRouterIdentity } from '../navigate'
|
|
|
|
export function NavigateToOther() {
|
|
const pathname = usePathname()
|
|
const otherPage = pathname.endsWith('/one')
|
|
? pathname.replace('/one', '/two')
|
|
: pathname.endsWith('/two')
|
|
? pathname.replace('/two', '/one')
|
|
: (() => {
|
|
throw new Error('Unrecognized pathname: ' + pathname)
|
|
})()
|
|
|
|
return <NavigateAndTrackRouterIdentity href={otherPage} />
|
|
}
|