Repository navigation
bug: React IonRouterOutlet throws when unmounted before initialization completes #31513
Description
Prerequisites
- I have read the Contributing Guidelines.
- I agree to follow the Code of Conduct.
- I have searched for existing issues that already report this problem, without success.
Ionic Framework Version
v9.x
Current Behavior
While optimizing page loading in my Ionic React app, I started seeing intermittent uncaught exceptions during registration and onboarding in Playwright.
Astra analysis:
Unmounting an IonRouterOutlet with ionPage before its deferred initialization callback runs causes an uncaught exception:
TypeError: Cannot read properties of null (reading 'classList')
at http://localhost:5173/node_modules/.vite/deps/chunk-K6ONCLJS.js?v=7fa17f37:13510:19
at http://localhost:5173/node_modules/.vite/deps/chunk-ANOI66QA.js?v=7fa17f37:35:75
The first frame is the componentOnReady callback in OutletPageManager.componentDidMount().
The reproduction mounts the outlet, then removes it in the parent component's layout effect. This makes the problematic lifecycle ordering deterministic: the child's componentDidMount schedules initialization before the parent's layout effect removes it. No framework internals are mocked or patched, and no timers or network throttling are needed.
Expected Behavior
If the outlet is unmounted before initialization completes, the pending callback should exit without accessing the cleared ref, changing page classes, or registering a stale outlet. No uncaught error should occur.
Steps to Reproduce
-
Clone the reproduction and install dependencies:
git clone --branch outletPageManager https://github.com/ptmkenny/ionic-react-router-6-test.git cd ionic-react-router-6-test npm install npm run dev -
Open the URL printed by Vite, normally
http://localhost:5173/. -
Click Mount and unmount outlet.
-
Observe Attempts: 1, Uncaught errors: 1, and the
classListTypeError printed on the page and in the console. -
Click again. Each click mounts and removes a new outlet and adds another error. Expected: the error counter remains zero.
Code Reproduction URL
https://github.com/ptmkenny/ionic-react-router-6-test/tree/outletPageManager
Ionic Info
Ionic:
Ionic CLI : 7.2.1 (/home/node/.npm/_npx/f6fddb685269761d/node_modules/@ionic/cli)
Ionic Framework : @ionic/react 9.0.6
Capacitor:
Capacitor CLI : 8.0.0
@capacitor/android : not installed
@capacitor/core : 8.0.0
@capacitor/ios : not installed
Utility:
cordova-res : not installed globally
native-run : 2.0.1
System:
NodeJS : v26.10.0 (/usr/local/bin/node)
npm : 11.19.1
OS : Linux 6.18
Additional Information
From Astra:
Root cause
In OutletPageManager.tsx, componentDidMount() checks this.ionRouterOutlet before scheduling componentOnReady. The callback later reads this.ionRouterOutlet! again and immediately accesses el.classList. React can clear the ref between scheduling and execution. The non-null assertion does not prevent runtime null access.
The same unsafe callback exists in upstream main at 643584b3ac (2026-10-01). A check made only before scheduling is insufficient. The callback must also belong to the current mount and outlet when it executes.
Activity
ptmkenny commentedon Oct 1, 2026
I don't have a proposed fix for this, but I got Astra to generate a patch that works for me locally; I pushed that to my own repo here: https://github.com/ptmkenny/ionic-framework/tree/outletPageManager. This is for reference only.
fix(react): prevent error when an outlet unmounts before it's ready (i…
ShaneK commentedon Oct 7, 2026
Hey! Thanks for the bug report! This has been fixed in v9.0.7!