chore: migrate NavManager to a functional component

This commit is contained in:
Sean Perkins
2023-07-03 13:16:24 -04:00
parent 02a2b393b8
commit ec69d340c9
3 changed files with 73 additions and 82 deletions

View File

@@ -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.

View File

@@ -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;

View File

@@ -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>
);
};