Skip to content

fix(react-router): dispatch view lifecycle events on non-animated transitions - #31497

Open
ShaneK wants to merge 1 commit into
mainfrom
fix/rr6-lifecycle-non-animated
Open

ShaneK wants to merge 1 commit into
mainfrom
fix/rr6-lifecycle-non-animated

Conversation

@ShaneK

@ShaneK ShaneK commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

Issue number: resolves #31479


What is the current behavior?

Currently, switching tabs or following a link with routerDirection="none" fires none of the four view lifecycle events, so a page that loads its data in useIonViewWillEnter renders empty. The non-animated branch of StackManager.transitionPage() skips routerOutlet.commit() and swaps the page classes itself to avoid intermediate paints, and core dispatches all four events from inside commit(), so they never fire. A capturing listener on the ion-router-outlet gets nothing either, so it isn't a problem with the hooks.

What is the new behavior?

That branch now dispatches the four events itself, in the same order core's transition() uses. The class swap moved to after all four, so the leaving page is still on screen for its leave events and the entering page is revealed only once they've fired. That's what core does on the animated path, where beforeTransition un-hides the leaving page and ion-page-hidden only goes back on after commit() resolves, and it matters because ion-page-hidden is display: none, so a useIonViewDidLeave handler reading scrollTop off the outgoing page was getting 0.

The two dispatch sites that already existed in this file for out-of-scope and root navigation now share the same helper.

Does this introduce a breaking change?

  • Yes
  • No

Other information

The events used to come from core here. This path called commit(enteringEl, undefined, { duration: 0 }) until 12f0d5e dropped it to fix a white flash during tab switches, and with no leaving element core took its noAnimation branch and fired the enter pair, so the enter half of this is a regression from that commit. Putting the call back would get the events plus focus and z-index handling from core for free, but it risks the flash it was removed for, so this dispatches them directly instead.

The patch on the issue fires the enter events unconditionally. This gates them on the generation check so a superseded transition doesn't announce an entry, and it skips the leave events when the leaving page already has ion-page-hidden, because two transitions sharing a leaving element would otherwise run its useIonViewDidLeave teardown twice. The check is the class rather than isViewVisible since a nested outlet marks its leaving page visibility: hidden before we get here and still needs ionViewDidLeave to unmount.

Preview:

Current Dev Build

9.0.6-dev.11790615145.1d8c56a2

@ShaneK
ShaneK requested a review from a team as a code owner September 28, 2026 17:04
@vercel

vercel Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
ionic-framework Ready Ready Preview Sep 28, 2026 5:05pm UTC

Request Review

This branch was successfully deployed

1 active deployment
Preview — d8c56a25 Deployed Sep 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: react @ionic/react package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: (react-router): lifecycle events do not fire on tab switches or routerDirection="none" navigation

1 participant