From ec69d340c99efcce8eb7cac3161b38bcd0a3f828 Mon Sep 17 00:00:00 2001 From: Sean Perkins Date: Mon, 3 Jul 2023 13:16:24 -0400 Subject: [PATCH] chore: migrate NavManager to a functional component --- .../src/ReactRouter/IonReactRouter.tsx | 2 +- .../src/ReactRouter/IonRouter.tsx | 8 +- packages/react/src/routing/NavManager.tsx | 145 ++++++++---------- 3 files changed, 73 insertions(+), 82 deletions(-) diff --git a/packages/react-router/src/ReactRouter/IonReactRouter.tsx b/packages/react-router/src/ReactRouter/IonReactRouter.tsx index 40208abe15..66d809b2d4 100644 --- a/packages/react-router/src/ReactRouter/IonReactRouter.tsx +++ b/packages/react-router/src/ReactRouter/IonReactRouter.tsx @@ -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. diff --git a/packages/react-router/src/ReactRouter/IonRouter.tsx b/packages/react-router/src/ReactRouter/IonRouter.tsx index 5dc802dcc4..4e5f39065c 100644 --- a/packages/react-router/src/ReactRouter/IonRouter.tsx +++ b/packages/react-router/src/ReactRouter/IonRouter.tsx @@ -14,7 +14,7 @@ export interface LocationState { routerOptions?: { as?: string; unmount?: boolean }; } -function IonRouterInner(props: PropsWithChildren) { +const IonRouter = ({ children }: PropsWithChildren<{}>) => { const location = useLocation(); const params = useParams(); const navigate = useNavigate(); @@ -299,10 +299,10 @@ function IonRouterInner(props: PropsWithChildren) { onResetTab={handleResetTab} locationHistory={locationHistory.current} > - {props.children} + {children} ); -} +}; -export const IonRouter = IonRouterInner; +export default IonRouter; diff --git a/packages/react/src/routing/NavManager.tsx b/packages/react/src/routing/NavManager.tsx index 2739694780..485c5627c3 100644 --- a/packages/react/src/routing/NavManager.tsx +++ b/packages/react/src/routing/NavManager.tsx @@ -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 { - ionRouterContextValue: IonRouterContextState = { +export const NavManager = ({ children, ...props }: PropsWithChildren) => { + 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 { - 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 ( - - - {this.props.children} - - - ); - } -} + return ( + true, + navigate, + getIonRedirect, + getIonRoute, + getStackManager, + getPageManager, + routeInfo, + setCurrentTab: onSetCurrentTab, + changeTab: onChangeTab, + resetTab: onResetTab, + }} + > + {children} + + ); +};