Skip to content

Commit f323d69

Browse files
committed
refactor(tabs, tab-bar): use context for router outlet
1 parent 6b01200 commit f323d69

File tree

3 files changed

+12
-23
lines changed

3 files changed

+12
-23
lines changed

packages/react/src/components/navigation/IonTabBar.tsx

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { IonTabBarInner } from '../inner-proxies';
88
import { createForwardRef } from '../utils';
99

1010
import { IonTabButton } from './IonTabButton';
11+
import { IonTabsContext } from './IonTabsContext';
1112

1213
type IonTabBarProps = LocalJSX.IonTabBar &
1314
IonicReactProps & {
@@ -32,7 +33,7 @@ interface InternalProps extends IonTabBarProps {
3233
* are being used as a basic tab navigation or with
3334
* the router.
3435
*/
35-
routerOutletRef?: React.RefObject<HTMLIonRouterOutletElement> | undefined;
36+
hasRouterOutlet: boolean;
3637
}
3738

3839
interface TabUrls {
@@ -196,33 +197,13 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
196197
) {
197198
const tappedTab = this.state.tabs[e.detail.tab];
198199
const originalHref = tappedTab.originalHref;
199-
let hasIonRouterOutlet = !!this.props.routerOutletRef?.current;
200-
201-
/**
202-
* If `hasRouterOutlet` prop is not provided,
203-
* then the `IonTabBar` could not be found
204-
* within the slotted content of `IonTabs`.
205-
* This means that the tab bar might not
206-
* have been passed as a direct child of
207-
* `IonTabs`.
208-
*
209-
* In this case, the router outlet needs to be
210-
* searched for within the `IonTabBar` component.
211-
* This is necessary to determine if the tabs
212-
* are being used as a basic tab navigation or
213-
* with the router.
214-
*/
215-
if (!hasIonRouterOutlet) {
216-
const ionRouterOutlet = this.tabBarRef.current?.closest('ion-tabs')?.querySelector('ion-router-outlet');
217-
hasIonRouterOutlet = !!ionRouterOutlet;
218-
}
219200

220201
/**
221202
* If the router outlet is not defined, then the tabs is being used
222203
* as a basic tab navigation without the router. In this case, we
223204
* don't want to update the href else the URL will change.
224205
*/
225-
const currentHref = hasIonRouterOutlet ? e.detail.href : '';
206+
const currentHref = this.props.hasRouterOutlet ? e.detail.href : '';
226207
const { activeTab: prevActiveTab } = this.state;
227208

228209
if (onClickFn) {
@@ -246,7 +227,7 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
246227
if (this.props.onIonTabsDidChange) {
247228
this.props.onIonTabsDidChange(new CustomEvent('ionTabDidChange', { detail: { tab: e.detail.tab } }));
248229
}
249-
if (hasIonRouterOutlet) {
230+
if (this.props.hasRouterOutlet) {
250231
this.setActiveTabOnContext(e.detail.tab);
251232
this.context.changeTab(e.detail.tab, currentHref, e.detail.routeOptions);
252233
}
@@ -296,12 +277,15 @@ class IonTabBarUnwrapped extends React.PureComponent<InternalProps, IonTabBarSta
296277

297278
const IonTabBarContainer: React.FC<InternalProps> = React.memo<InternalProps>(({ forwardedRef, ...props }) => {
298279
const context = useContext(NavContext);
280+
const tabsContext = useContext(IonTabsContext);
281+
299282
return (
300283
<IonTabBarUnwrapped
301284
ref={forwardedRef}
302285
{...(props as any)}
303286
routeInfo={props.routeInfo || context.routeInfo || { pathname: window.location.pathname }}
304287
onSetCurrentTab={context.setCurrentTab}
288+
hasRouterOutlet={tabsContext.hasRouterOutlet}
305289
>
306290
{props.children}
307291
</IonTabBarUnwrapped>

packages/react/src/components/navigation/IonTabs.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export const IonTabs = /*@__PURE__*/ (() =>
7272
ionTabContextState: IonTabsContextState = {
7373
activeTab: undefined,
7474
selectTab: () => false,
75+
hasRouterOutlet: false,
7576
};
7677

7778
constructor(props: Props) {
@@ -123,6 +124,8 @@ export const IonTabs = /*@__PURE__*/ (() =>
123124
hasTab = true;
124125
}
125126

127+
this.ionTabContextState.hasRouterOutlet = !!outlet;
128+
126129
let childProps: any = {
127130
ref: this.tabBarRef,
128131
routerOutletRef: this.routerOutletRef,

packages/react/src/components/navigation/IonTabsContext.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import React from 'react';
33
export interface IonTabsContextState {
44
activeTab: string | undefined;
55
selectTab: (tab: string) => boolean;
6+
hasRouterOutlet: boolean;
67
}
78

89
export const IonTabsContext = React.createContext<IonTabsContextState>({
910
activeTab: undefined,
1011
selectTab: () => false,
12+
hasRouterOutlet: false,
1113
});

0 commit comments

Comments
 (0)