mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
chore: migrate NavManager to a functional component
This commit is contained in:
@@ -3,7 +3,7 @@ import React from 'react';
|
||||
import type { BrowserRouterProps } from 'react-router-dom';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
|
||||
import { IonRouter } from './IonRouter';
|
||||
import IonRouter from './IonRouter';
|
||||
|
||||
/**
|
||||
* Wrapper around react-router-dom's BrowserRouter that provides a context for IonRouterOutlet.
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface LocationState {
|
||||
routerOptions?: { as?: string; unmount?: boolean };
|
||||
}
|
||||
|
||||
function IonRouterInner(props: PropsWithChildren<any>) {
|
||||
const IonRouter = ({ children }: PropsWithChildren<{}>) => {
|
||||
const location = useLocation();
|
||||
const params = useParams();
|
||||
const navigate = useNavigate();
|
||||
@@ -299,10 +299,10 @@ function IonRouterInner(props: PropsWithChildren<any>) {
|
||||
onResetTab={handleResetTab}
|
||||
locationHistory={locationHistory.current}
|
||||
>
|
||||
{props.children}
|
||||
{children}
|
||||
</NavManager>
|
||||
</RouteManagerContext.Provider>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const IonRouter = IonRouterInner;
|
||||
export default IonRouter;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { AnimationBuilder } from '@ionic/core/components';
|
||||
import React from 'react';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
|
||||
import type { IonRouterContextState } from '../components/IonRouterContext';
|
||||
import { IonRouterContext } from '../components/IonRouterContext';
|
||||
import type { NavContextState } from '../contexts/NavContext';
|
||||
import { NavContext } from '../contexts/NavContext';
|
||||
import type { RouteAction } from '../models/RouteAction';
|
||||
import type { RouteInfo } from '../models/RouteInfo';
|
||||
@@ -36,8 +36,27 @@ interface NavManagerProps {
|
||||
locationHistory: LocationHistory;
|
||||
}
|
||||
|
||||
export class NavManager extends React.PureComponent<NavManagerProps, NavContextState> {
|
||||
ionRouterContextValue: IonRouterContextState = {
|
||||
export const NavManager = ({ children, ...props }: PropsWithChildren<NavManagerProps>) => {
|
||||
const {
|
||||
routeInfo,
|
||||
onNativeBack,
|
||||
onNavigateBack,
|
||||
onNavigate,
|
||||
onSetCurrentTab,
|
||||
onChangeTab,
|
||||
onResetTab,
|
||||
stackManager,
|
||||
ionRedirect,
|
||||
ionRoute,
|
||||
locationHistory,
|
||||
} = props;
|
||||
|
||||
const getPageManager = useCallback(() => PageManager, []);
|
||||
const getIonRedirect = useCallback(() => ionRedirect, []);
|
||||
const getIonRoute = useCallback(() => ionRoute, []);
|
||||
const getStackManager = useCallback(() => stackManager, []);
|
||||
|
||||
const ionRouterContextValue: IonRouterContextState = {
|
||||
push: (
|
||||
pathname: string,
|
||||
routerDirection?: RouterDirection,
|
||||
@@ -45,95 +64,67 @@ export class NavManager extends React.PureComponent<NavManagerProps, NavContextS
|
||||
routerOptions?: RouterOptions,
|
||||
animationBuilder?: AnimationBuilder
|
||||
) => {
|
||||
this.navigate(pathname, routerDirection, routeAction, animationBuilder, routerOptions);
|
||||
navigate(pathname, routerDirection, routeAction, animationBuilder, routerOptions);
|
||||
},
|
||||
back: (animationBuilder?: AnimationBuilder) => {
|
||||
this.goBack(undefined, animationBuilder);
|
||||
goBack(undefined, animationBuilder);
|
||||
},
|
||||
canGoBack: () => this.props.locationHistory.canGoBack(),
|
||||
nativeBack: () => this.props.onNativeBack(),
|
||||
routeInfo: this.props.routeInfo,
|
||||
canGoBack: () => locationHistory.canGoBack(),
|
||||
nativeBack: () => onNativeBack(),
|
||||
routeInfo,
|
||||
};
|
||||
|
||||
constructor(props: NavManagerProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
goBack: this.goBack.bind(this),
|
||||
hasIonicRouter: () => true,
|
||||
navigate: this.navigate.bind(this),
|
||||
getIonRedirect: this.getIonRedirect.bind(this),
|
||||
getIonRoute: this.getIonRoute.bind(this),
|
||||
getStackManager: this.getStackManager.bind(this),
|
||||
getPageManager: this.getPageManager.bind(this),
|
||||
routeInfo: this.props.routeInfo,
|
||||
setCurrentTab: this.props.onSetCurrentTab,
|
||||
changeTab: this.props.onChangeTab,
|
||||
resetTab: this.props.onResetTab,
|
||||
useEffect(() => {
|
||||
const handleHardwareBackButton = (e: any) => {
|
||||
e.detail.register(0, (processNextHandler: () => void) => {
|
||||
onNativeBack();
|
||||
processNextHandler();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (typeof document !== 'undefined') {
|
||||
this.handleHardwareBackButton = this.handleHardwareBackButton.bind(this);
|
||||
document.addEventListener('ionBackButton', this.handleHardwareBackButton);
|
||||
document.addEventListener('ionBackButton', handleHardwareBackButton);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (typeof document !== 'undefined') {
|
||||
document.removeEventListener('ionBackButton', this.handleHardwareBackButton);
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
if (typeof document !== 'undefined') {
|
||||
document.removeEventListener('ionBackButton', handleHardwareBackButton);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
handleHardwareBackButton(e: any) {
|
||||
e.detail.register(0, (processNextHandler: () => void) => {
|
||||
this.nativeGoBack();
|
||||
processNextHandler();
|
||||
});
|
||||
}
|
||||
const goBack = (route?: string | RouteInfo, animationBuilder?: AnimationBuilder) => {
|
||||
onNavigateBack(route, animationBuilder);
|
||||
};
|
||||
|
||||
goBack(route?: string | RouteInfo, animationBuilder?: AnimationBuilder) {
|
||||
this.props.onNavigateBack(route, animationBuilder);
|
||||
}
|
||||
|
||||
nativeGoBack() {
|
||||
this.props.onNativeBack();
|
||||
}
|
||||
|
||||
navigate(
|
||||
const navigate = (
|
||||
path: string,
|
||||
direction: RouterDirection = 'forward',
|
||||
action: RouteAction = 'push',
|
||||
animationBuilder?: AnimationBuilder,
|
||||
options?: any,
|
||||
tab?: string
|
||||
) {
|
||||
this.props.onNavigate(path, action, direction, animationBuilder, options, tab);
|
||||
}
|
||||
) => {
|
||||
onNavigate(path, action, direction, animationBuilder, options, tab);
|
||||
};
|
||||
|
||||
getPageManager() {
|
||||
return PageManager;
|
||||
}
|
||||
|
||||
getIonRedirect() {
|
||||
return this.props.ionRedirect;
|
||||
}
|
||||
|
||||
getIonRoute() {
|
||||
return this.props.ionRoute;
|
||||
}
|
||||
|
||||
getStackManager() {
|
||||
return this.props.stackManager;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<NavContext.Provider value={{ ...this.state, routeInfo: this.props.routeInfo }}>
|
||||
<IonRouterContext.Provider value={{ ...this.ionRouterContextValue, routeInfo: this.props.routeInfo }}>
|
||||
{this.props.children}
|
||||
</IonRouterContext.Provider>
|
||||
</NavContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<NavContext.Provider
|
||||
value={{
|
||||
goBack,
|
||||
hasIonicRouter: () => true,
|
||||
navigate,
|
||||
getIonRedirect,
|
||||
getIonRoute,
|
||||
getStackManager,
|
||||
getPageManager,
|
||||
routeInfo,
|
||||
setCurrentTab: onSetCurrentTab,
|
||||
changeTab: onChangeTab,
|
||||
resetTab: onResetTab,
|
||||
}}
|
||||
>
|
||||
<IonRouterContext.Provider value={{ ...ionRouterContextValue, routeInfo }}>{children}</IonRouterContext.Provider>
|
||||
</NavContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user