fix(react-router): remove page transition flicker on outlet mounting (#24667)

Resolves #24666
This commit is contained in:
Sean Perkins
2022-01-27 16:29:52 -05:00
committed by GitHub
parent 6d7b1444b6
commit bdb5c421d2
5 changed files with 83 additions and 4 deletions

View File

@ -9,6 +9,14 @@ export class IonRouteInner extends React.PureComponent<IonRouteProps> {
path={this.props.path}
exact={this.props.exact}
render={this.props.render}
/**
* `computedMatch` is a private API in react-router v5 that
* has been removed in v6.
*
* This needs to be removed when we support v6.
*
* TODO: FW-647
*/
computedMatch={(this.props as any).computedMatch}
/>
);

View File

@ -29,6 +29,8 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
isInOutlet: () => true,
};
private pendingPageTransition = false;
constructor(props: StackManagerProps) {
super(props);
this.registerIonPage = this.registerIonPage.bind(this);
@ -46,8 +48,9 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
}
componentDidUpdate(prevProps: StackManagerProps) {
if (this.props.routeInfo.pathname !== prevProps.routeInfo.pathname) {
if (this.props.routeInfo.pathname !== prevProps.routeInfo.pathname || this.pendingPageTransition) {
this.handlePageTransition(this.props.routeInfo);
this.pendingPageTransition = false;
}
}
@ -57,9 +60,15 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
}
async handlePageTransition(routeInfo: RouteInfo) {
// If routerOutlet isn't quite ready, give it another try in a moment
if (!this.routerOutletElement || !this.routerOutletElement.commit) {
setTimeout(() => this.handlePageTransition(routeInfo), 10);
/**
* The route outlet has not mounted yet. We need to wait for it to render
* before we can transition the page.
*
* Set a flag to indicate that we should transition the page after
* the component has updated.
*/
this.pendingPageTransition = true;
} else {
let enteringViewItem = this.context.findViewItemByRouteInfo(routeInfo, this.id);
let leavingViewItem = this.context.findLeavingViewItemByRouteInfo(routeInfo, this.id);