mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix(react): fixng ion-router-outlet ref regresssion (#21786)
This commit is contained in:
@@ -55,7 +55,6 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
}
|
||||
|
||||
async handlePageTransition(routeInfo: RouteInfo) {
|
||||
// let shouldReRender = false;
|
||||
|
||||
// If routerOutlet isn't quite ready, give it another try in a moment
|
||||
if (!this.routerOutletElement || !this.routerOutletElement.commit) {
|
||||
@@ -172,6 +171,7 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
() => {
|
||||
this.forceUpdate();
|
||||
});
|
||||
|
||||
return (
|
||||
<StackContext.Provider value={this.stackContextValue}>
|
||||
{React.cloneElement(ionRouterOutlet as any, {
|
||||
@@ -179,6 +179,9 @@ export class StackManager extends React.PureComponent<StackManagerProps, StackMa
|
||||
if (ionRouterOutlet.props.setRef) {
|
||||
ionRouterOutlet.props.setRef(node);
|
||||
}
|
||||
if (ionRouterOutlet.props.forwardedRef) {
|
||||
ionRouterOutlet.props.forwardedRef.current = node;
|
||||
}
|
||||
this.routerOutletElement = node;
|
||||
const { ref } = ionRouterOutlet as any;
|
||||
if (typeof ref === 'function') {
|
||||
|
||||
@@ -3,7 +3,7 @@ cd ../../react
|
||||
npm run build
|
||||
npm pack
|
||||
cd ../react-router/test-app
|
||||
npm i ../../react/ionic-react-5.2.2.tgz
|
||||
npm i ../../react/ionic-react-5.2.3.tgz
|
||||
npm run start
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
const port = 3000;
|
||||
|
||||
describe('Multiple Tabs', () => {
|
||||
/*
|
||||
This spec tests that setting a ref on an IonRouterOutlet works
|
||||
*/
|
||||
|
||||
it('/outlet-ref, page should contain the id of the ion-router-outlet', () => {
|
||||
cy.visit(`http://localhost:${port}/outlet-ref`)
|
||||
cy.get('div').contains('main-outlet')
|
||||
cy.ionPageVisible('main')
|
||||
})
|
||||
|
||||
})
|
||||
@@ -33,6 +33,7 @@ import NestedOutlet from './pages/nested-outlet/NestedOutlet';
|
||||
import NestedOutlet2 from './pages/nested-outlet/NestedOutlet2';
|
||||
import ReplaceAction from './pages/replace-action/Replace';
|
||||
import TabsContext from './pages/tab-context/TabContext';
|
||||
import { OutletRef } from './pages/outlet-ref/OutletRef';
|
||||
debugger;
|
||||
const App: React.FC = () => {
|
||||
return (
|
||||
@@ -47,6 +48,7 @@ const App: React.FC = () => {
|
||||
<Route path="/nested-outlet2" component={NestedOutlet2} />
|
||||
<Route path="/replace-action" component={ReplaceAction} />
|
||||
<Route path="/tab-context" component={TabsContext} />
|
||||
<Route path="/outlet-ref" component={OutletRef} />
|
||||
</IonReactRouter>
|
||||
</IonApp>
|
||||
);
|
||||
|
||||
@@ -38,6 +38,9 @@ const Main: React.FC<MainProps> = () => {
|
||||
<IonItem routerLink="/tab-context">
|
||||
<IonLabel>Tab Context</IonLabel>
|
||||
</IonItem>
|
||||
<IonItem routerLink="/outlet-ref">
|
||||
<IonLabel>Outlet Ref</IonLabel>
|
||||
</IonItem>
|
||||
</IonList>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
import { IonRouterOutlet, IonPage, IonHeader, IonToolbar, IonTitle, IonContent } from '@ionic/react';
|
||||
import { Route } from 'react-router';
|
||||
|
||||
interface OutletRefProps {
|
||||
}
|
||||
|
||||
export const OutletRef: React.FC<OutletRefProps> = () => {
|
||||
|
||||
const ref = useRef<HTMLIonRouterOutletElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
console.log(ref);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<IonRouterOutlet id="main-outlet" ref={ref}>
|
||||
<Route path="/outlet-ref" render={() => {
|
||||
return <Main outletId={ref.current?.id} />;
|
||||
}} />
|
||||
</IonRouterOutlet>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
const Main: React.FC<{ outletId?: string; }> = ({ outletId }) => {
|
||||
return (
|
||||
<IonPage data-pageid="main">
|
||||
<IonHeader>
|
||||
<IonToolbar>
|
||||
<IonTitle>Main</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent>
|
||||
<div>{outletId}</div>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default Main;
|
||||
@@ -46,7 +46,7 @@ class IonRouterOutletContainer extends React.Component<InternalProps, InternalSt
|
||||
</OutletPageManager>
|
||||
) : (
|
||||
<StackManager routeInfo={this.context.routeInfo}>
|
||||
<IonRouterOutletInner {...props}>
|
||||
<IonRouterOutletInner {...props} forwardedRef={forwardedRef}>
|
||||
{children}
|
||||
</IonRouterOutletInner>
|
||||
</StackManager>
|
||||
|
||||
@@ -6,7 +6,10 @@ import { /*@__PURE__*/ createReactComponent } from './createComponent';
|
||||
export const IonTabButtonInner = /*@__PURE__*/createReactComponent<JSX.IonTabButton & { onIonTabButtonClick?: (e: CustomEvent) => void; }, HTMLIonTabButtonElement>('ion-tab-button');
|
||||
export const IonTabBarInner = /*@__PURE__*/createReactComponent<JSX.IonTabBar, HTMLIonTabBarElement>('ion-tab-bar');
|
||||
export const IonBackButtonInner = /*@__PURE__*/createReactComponent<Omit<JSX.IonBackButton, 'icon'>, HTMLIonBackButtonElement>('ion-back-button');
|
||||
export const IonRouterOutletInner = /*@__PURE__*/createReactComponent<JSX.IonRouterOutlet & { setRef?: (val: HTMLIonRouterOutletElement) => void; }, HTMLIonRouterOutletElement>('ion-router-outlet');
|
||||
export const IonRouterOutletInner = /*@__PURE__*/createReactComponent<JSX.IonRouterOutlet & {
|
||||
setRef?: (val: HTMLIonRouterOutletElement) => void;
|
||||
forwardedRef?: React.RefObject<HTMLIonRouterOutletElement>;
|
||||
}, HTMLIonRouterOutletElement>('ion-router-outlet');
|
||||
|
||||
// ionicons
|
||||
export const IonIconInner = /*@__PURE__*/createReactComponent<IoniconsJSX.IonIcon, HTMLIonIconElement>('ion-icon');
|
||||
|
||||
@@ -9,7 +9,7 @@ import { StackContext } from './StackContext';
|
||||
|
||||
interface OutletPageManagerProps {
|
||||
className?: string;
|
||||
forwardedRef?: React.RefObject<HTMLDivElement>;
|
||||
forwardedRef?: React.RefObject<HTMLIonRouterOutletElement>;
|
||||
routeInfo?: RouteInfo;
|
||||
StackManager: any;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user