Skip to content

Conversation

@acdlite
Copy link
Contributor

@acdlite acdlite commented Jan 3, 2026

Based on:


The Mutable type was used by an earlier implementation of App Router when the reducer used to run during React's render phase. It was used to prevent certain operations from running multiple times if an update was reapplied by React.

Now that router "reducer" actions run outside React's render phase, we no longer need this indirection — we can compute the next state object directly.

Most of the Mutable-related logic was deleted in previous PRs; this finishes the migration by inlining handleMutable into its callers.

@nextjs-bot
Copy link
Collaborator

nextjs-bot commented Jan 12, 2026

Tests Passed

@acdlite acdlite force-pushed the inline-handlemutable branch 2 times, most recently from 1b019e3 to 000079e Compare January 12, 2026 04:52
@acdlite acdlite force-pushed the inline-handlemutable branch from 000079e to fe11125 Compare January 12, 2026 17:35
@acdlite acdlite marked this pull request as ready for review January 12, 2026 17:37
@acdlite acdlite force-pushed the inline-handlemutable branch 3 times, most recently from 7369e09 to 4bfd70f Compare January 12, 2026 23:34
const currentRenderedSearch = state.renderedSearch
const currentFlightRouterState = state.tree
const shouldScroll = true
const shouldScroll = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was this an intentional behavior change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The net behavior is the same, it probably should have been false before but was working anyway for other reasons. There are lots of existing tests for this so I'm pretty confident it's safe.

Comment on lines 16 to 19
export const RedirectType = {
Push: 'push',
Replace: 'replace',
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep the casing from before this refactor, eg RedirectType.push rather than RedirectType.Push so we don't break apps that were depending on this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh oops that was unintentional, good catch

shouldScroll,
navigateType
).catch(() => {
// If the navigation fails, return the current state
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wonder if it's worth logging something during dev when this happens

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should though to be clear that's the current behavior, too

url.search === oldUrl.search &&
url.hash !== oldUrl.hash

// During a hash-only change, setting scrollableSegmeths to an empty
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// During a hash-only change, setting scrollableSegmeths to an empty
// During a hash-only change, setting scrollableSegments to an empty

@acdlite acdlite force-pushed the inline-handlemutable branch from 4bfd70f to 6b1f27d Compare January 14, 2026 02:38
The Mutable type was used by an earlier implementation of App Router
when the reducer used to run during React's render phase. It was used
to prevent certain operations from running multiple times if an
update was reapplied by React.

Now that router "reducer" actions run outside React's render phase,
we no longer need this indirection — we can compute the next state
object directly.

Most of the Mutable-related logic was deleted in previous PRs; this
finishes the migration by inlining handleMutable into its callers.
@acdlite acdlite force-pushed the inline-handlemutable branch from 6b1f27d to 09aa63c Compare January 14, 2026 16:59
@acdlite acdlite merged commit 8fe154f into vercel:canary Jan 14, 2026
149 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants