From e6e17eb43535108559b5d2120d3859c192c19587 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Fri, 13 Jun 2025 16:28:43 -0700 Subject: [PATCH] refactor(IonReactRouter): split component to use hooks correctly --- .../src/ReactRouter/IonReactRouter.tsx | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/packages/react-router/src/ReactRouter/IonReactRouter.tsx b/packages/react-router/src/ReactRouter/IonReactRouter.tsx index 081dbb95bc..919885256d 100644 --- a/packages/react-router/src/ReactRouter/IonReactRouter.tsx +++ b/packages/react-router/src/ReactRouter/IonReactRouter.tsx @@ -7,21 +7,29 @@ import type { Action as HistoryAction, Location as HistoryLocation } from 'history'; import type { PropsWithChildren } from 'react'; -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useRef, useCallback } from 'react'; import type { BrowserRouterProps } from 'react-router-dom'; import { BrowserRouter, useLocation, useNavigationType } from 'react-router-dom'; import { IonRouter } from './IonRouter'; -export const IonReactRouter = ({ children }: PropsWithChildren) => { +/** + * This component acts as a bridge to ensure React Router hooks like + * `useLocation` and `useNavigationType` are called within the valid + * context of a ``. + * + * It was split from `IonReactRouter` because these hooks must be + * descendants of a `` component, which `BrowserRouter` provides. + */ +const RouterContent = ({ children }: PropsWithChildren<{}>) => { const location = useLocation(); const navigationType = useNavigationType(); const historyListenHandler = useRef<(location: HistoryLocation, action: HistoryAction) => void>(); - const registerHistoryListener = (cb: (location: HistoryLocation, action: HistoryAction) => void) => { + const registerHistoryListener = useCallback((cb: (location: HistoryLocation, action: HistoryAction) => void) => { historyListenHandler.current = cb; - }; + }, []); /** * Processes navigation changes within the application. @@ -35,19 +43,27 @@ export const IonReactRouter = ({ children }: PropsWithChildren { + const handleHistoryChange = useCallback((loc: HistoryLocation, act: HistoryAction) => { if (historyListenHandler.current) { - historyListenHandler.current(location, action); + historyListenHandler.current(loc, act); } - }; + }, []); useEffect(() => { handleHistoryChange(location, navigationType); - }, [location, navigationType]); + }, [location, navigationType, handleHistoryChange]); return ( - - {children} + + {children} + + ); +}; + +export const IonReactRouter = ({ children, ...browserRouterProps }: PropsWithChildren) => { + return ( + + {children} ); };