Ionic version:
5.0.1
Here is a repo with a minimal code to reproduce the bug:
https://github.com/OoDeLally/ionic-nested-router-outlet-bug
Ionic info:
â–¶ ionic info
Ionic:
Ionic CLI : 5.4.16 (/home/pascal/.nvm/versions/node/v8.16.0/lib/node_modules/ionic)
Ionic Framework : @ionic/react 5.0.1
Utility:
cordova-res : not installed
native-run (update available: 0.3.0) : 0.2.9
System:
NodeJS : v8.16.0 (/home/pascal/.nvm/versions/node/v8.16.0/bin/node)
npm : 6.4.1
OS : Linux 4.15
Hi, any news of this?
I've tried to investigate checking the source code, but it seems beyond my level of understanding.
All of these issue links show the same problem that I am having trouble with. I replaced IonRouterOutlet with Switch, but IonTabs requires IonRouterOutlet, and I must delete IonTabs, and the app looks like ugly.
Probably, the problem is caused by IonRouterOutlet.
https://github.com/ionic-team/ionic/issues/20844
https://github.com/ionic-team/ionic/issues/20597
https://github.com/ionic-team/ionic/issues/20298
Duplicate of #20298 #20597 #20844
Anybody? This is a huge blocker for me
For me too... So far the workaround we use is to force a complete page reload (window.location = '...'
).
But this is definitely ugly, as the whole page flickers and we lose the parent state.
window.location
No, God, please, no :) Try this https://github.com/ionic-team/ionic/issues/20707#issuecomment-598806108
window.location
No, God, please, no :) Try this #20707 (comment)
It doesn't work for us.
When using <Switch>
, the parent component successfully unmounts, but it also unmounts when it should not (when the path changes but should still keep the parent component mounted), leading to a blank page, without any kind of console error.
Staying with window.location = '...'
for now, regarless of how ugly it is.
window.location
No, God, please, no :) Try this #20707 (comment)
It doesn't work for us.
When using<Switch>
, the parent component successfully unmounts, but it also unmounts when it should not (when the path changes but should still keep the parent component mounted), leading to a blank page, without any kind of console error.Staying with
window.location = '...'
for now, regarless of how ugly it is.
Did you try Ionic lifecycle methods?
Especially this one
useIonViewDidLeave(() => {
console.log('ionViewDidLeave event fired');
});
Did you try Ionic lifecycle methods?
Especially this one
useIonViewDidLeave(() => { console.log('ionViewDidLeave event fired'); });
I just did. None of the 4 events in https://ionicframework.com/docs/react/lifecycle was fired.
I'm also experiencing the same issue, no lifecyle method will be fired. Tried both class and functional component using the ionic docs.
Hello all,
I'm looking into this now, hope to have something to report on soon.
Hi All,
We have a dev release that provides better support for nested IonRouterOutlet components. There is a new prop on IonRouterOutlet that lets the router know it is a nested outlet to better perform the transition.
If your'e outlet is a nested outlet directly rendered by a Route in a parent outlet, then use the ionPage
prop on the IonRouterOutlet. Here is an example:
App.tsx:
const App: React.FC = () => (
<IonRouterOutlet>
<Route path="/sub1" component={Sub1Outlet} />
<Route path="/sub2" component={Sub2Outlet} />
</IonRouterOutlet>
);
Sub1Outlet.tsx:
const Sub1Outlet: React.FC = () => (
<IonRouterOutlet ionPage>
<Route path="/sub1" exact={true}
render={() => <Redirect to="/sub1/page" />} />
<Route path="/sub1/page" component={Page1} exact={true} />
</IonRouterOutlet>
);
Sub2Outlet.tsx:
const Sub2Outlet: React.FC = () => (
<IonRouterOutlet ionPage>
<Route path="/sub2" exact={true}
render={() => <Redirect to="/sub2/page" />} />
<Route path="/sub2/page" component={Page2} exact={true} />
</IonRouterOutlet>
);
If you can, could you try to install it and let us know if it fixes the issue and if you run into any others? To install it run:
npm i @ionic/[email protected] @ionic/[email protected]
If all goes good this should be available in the next Ionic release.
Thanks!
It didn't unmount the component for me. For now I will stick with routerDirection="back"
. Although it's not correct, it's working the way I need
The issue continues. There is no need for nested ionrouteroutlet. The problem occurs at only one router.
https://github.com/ionic-team/ionic-framework/issues/20298
https://github.com/ionic-team/ionic/issues/20844
https://github.com/ionic-team/ionic/issues/20597
@elylucas thanks for the fix! I'm noticing that going "back" from nested routes seems to have no transition animation when going back from a "level-3" nested route to a "level-2" nested route.
I first noticed this issue with a single layer of routes (no nesting) and an apollo query with the no-cache
option. Desired outcome, anytime i navigate to page X it would re-query the backend. I was surprised to see it not making the query a 2nd or more times. After days of searching git issues and changing versions of apollo/ionic etc i tried a useEffect callback function and noticed it wasn't working which is what apollo's useQuery uses to refetch.
All that to say i think the not unmounting components on forward
and none
directions is a premature optimization.
What if we made this an option on the Route?
It didn't unmount the component for me. For now I will stick with
routerDirection="back"
. Although it's not correct, it's working the way I need
What did you apply routerDirection="back" on?
Hello @basicBrogrammer, I started working on a react app, currently it does not deviate much from the default one generated by ionic start with a side menu. It does not have nested routing.
I have pages on different routes and I noticed the components do not unmount when I navigate from one route to the other, which for my use case is not good, as I want to refresh the content that I show when the user selects a view from the menu.
I could work it around by replacing IonRouterOutlet with a Switch, and wrapping it an IonContent to give it an id, but I can not judge what kind of side effects it would have. I think that the existing apis should give the developer control on when the component under a route is persisted or not, once the user leaves the route.
I think this is similar to what you described on https://github.com/ionic-team/ionic-framework/issues/20597#issuecomment-682473789, if I understood it well.
Hi All,
We have a dev release that provides better support for nested IonRouterOutlet components. There is a new prop on IonRouterOutlet that lets the router know it is a nested outlet to better perform the transition.
If your'e outlet is a nested outlet directly rendered by a Route in a parent outlet, then use the
ionPage
prop on the IonRouterOutlet. Here is an example:App.tsx:
const App: React.FC = () => ( <IonRouterOutlet> <Route path="/sub1" component={Sub1Outlet} /> <Route path="/sub2" component={Sub2Outlet} /> </IonRouterOutlet> );
Sub1Outlet.tsx:
const Sub1Outlet: React.FC = () => ( <IonRouterOutlet ionPage> <Route path="/sub1" exact={true} render={() => <Redirect to="/sub1/page" />} /> <Route path="/sub1/page" component={Page1} exact={true} /> </IonRouterOutlet> );
Sub2Outlet.tsx:
const Sub2Outlet: React.FC = () => ( <IonRouterOutlet ionPage> <Route path="/sub2" exact={true} render={() => <Redirect to="/sub2/page" />} /> <Route path="/sub2/page" component={Page2} exact={true} /> </IonRouterOutlet> );
If you can, could you try to install it and let us know if it fixes the issue and if you run into any others? To install it run:
npm i @ionic/[email protected] @ionic/[email protected]
If all goes good this should be available in the next Ionic release.
Thanks!
This seemed like a promising take but it didn't work for me. I assume it's because I have the IonRouterOutlet
wrapped in a Suspense
component. I have resorted to putting up a 404
page. I feel this is much better than using a Switch
which makes the app lose the lifecycle events and caching, and also the routing animations. I hope we will have that Redirect
working in IonRouterOutlet
soon.
Hello @basicBrogrammer, I started working on a react app, currently it does not deviate much from the default one generated by ionic start with a side menu. It does not have nested routing.
I have pages on different routes and I noticed the components do not unmount when I navigate from one route to the other, which for my use case is not good, as I want to refresh the content that I show when the user selects a view from the menu.I could work it around by replacing IonRouterOutlet with a Switch, and wrapping it an IonContent to give it an id, but I can not judge what kind of side effects it would have. I think that the existing apis should give the developer control on when the component under a route is persisted or not, once the user leaves the route.
I think this is similar to what you described on #20597 (comment), if I understood it well.
I think if you replace IonRouterOutlet with a switch you won't get the ION transition animations. You can change the direction on the given route to "back" and it will reload .... or at least it did last time i played with it.
routerDirection
I added routerDirection back to any link going to the given route that i wanted to "remount"
what is the state on this issue?
Nested routes result in breaking third party libraries (replacing ionRouterOutlet with Switch works)
anyways navigation is crucial
what is the state on this issue?
Nested routes result in breaking third party libraries (replacing ionRouterOutlet with Switch works)
anyways navigation is crucial
You have to remember that replacing IonRouterOutlet with a Switch will mean converting all your useIonViewDidEnter with useEffects and lose animations.
Most helpful comment
Hello all,
I'm looking into this now, hope to have something to report on soon.