feat(mobile): add lazy loading support to TabScreen component

- Introduced a `lazy` prop to the `TabScreen` and `TabScreenComponent` interfaces to enable lazy loading of tab screens.
- Updated the `TabScreen` implementation to conditionally render based on the `lazy` prop, improving performance by loading screens only when necessary.
- Set the `lazy` property to `true` for the `DiscoverTabScreen` to utilize the new functionality.

These changes enhance the tab navigation experience by optimizing screen loading behavior.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei 2025-03-20 13:52:42 +08:00
parent 51e517babd
commit a635c242b4
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
3 changed files with 18 additions and 6 deletions

View File

@ -18,6 +18,7 @@ export interface TabScreenProps {
title: string
tabScreenIndex: number
renderIcon?: (props: TabbarIconProps) => React.ReactNode
lazy?: boolean
}
export const TabScreen: FC<PropsWithChildren<Omit<TabScreenProps, "tabScreenIndex">>> = ({
children,
@ -32,7 +33,8 @@ export const TabScreen: FC<PropsWithChildren<Omit<TabScreenProps, "tabScreenInde
} = useContext(BottomTabContext)
const setTabScreens = useSetAtom(tabScreens)
useEffect(() => {
const mergedProps = useMemo(() => {
const propsFromChildren: Partial<TabScreenProps> = {}
if (children && typeof children === "object") {
const childType = (children as any).type as TabScreenComponent
@ -42,13 +44,20 @@ export const TabScreen: FC<PropsWithChildren<Omit<TabScreenProps, "tabScreenInde
if ("title" in childType) {
propsFromChildren.title = childType.title
}
if ("lazy" in childType) {
propsFromChildren.lazy = childType.lazy
}
}
return {
...propsFromChildren,
...props,
}
}, [children, props])
useEffect(() => {
setTabScreens((prev) => [
...prev,
{
...propsFromChildren,
...props,
...mergedProps,
tabScreenIndex,
},
])
@ -58,7 +67,7 @@ export const TabScreen: FC<PropsWithChildren<Omit<TabScreenProps, "tabScreenInde
prev.filter((tabScreen) => tabScreen.tabScreenIndex !== tabScreenIndex),
)
}
}, [setTabScreens, props, tabScreenIndex, children])
}, [setTabScreens, props, tabScreenIndex, children, mergedProps])
const currentSelectedIndex = useAtomValue(currentIndexAtom)
@ -87,7 +96,7 @@ export const TabScreen: FC<PropsWithChildren<Omit<TabScreenProps, "tabScreenInde
}),
[tabScreenIndex, props.title],
)
const shouldLoadReact = isSelected || isLoadedBefore
const shouldLoadReact = mergedProps.lazy ? isSelected || isLoadedBefore : true
return (
<TabScreenNative style={StyleSheet.absoluteFill}>

View File

@ -8,4 +8,6 @@ export type TabbarIconProps = {
export type TabScreenComponent = FC & {
tabBarIcon?: (props: TabbarIconProps) => React.ReactNode
title?: string
lazy?: boolean
}

View File

@ -40,3 +40,4 @@ DiscoverTabScreen.tabBarIcon = ({ focused, color }) => {
}
DiscoverTabScreen.title = "Discover"
DiscoverTabScreen.lazy = true