Skip to content

Commit

Permalink
Merge pull request #847 from thundersdata-frontend/rn-issue
Browse files Browse the repository at this point in the history
feat: 为Tabs增加lazy加载的功能
  • Loading branch information
chj-damon authored Apr 15, 2024
2 parents fcd33ed + 46c801f commit 273401f
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/nice-pans-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@td-design/react-native-tabs': minor
---

feat: 为Tabs增加lazy功能
51 changes: 51 additions & 0 deletions packages/react-native-tabs/src/SceneView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { useEffect } from 'react';
import { View } from 'react-native';

import { useSafeState } from '@td-design/rn-hooks';

export default function SceneView({
lazy,
currentPage,
index,
children,
}: {
lazy: boolean;
currentPage: number;
index: number;
children: (props: { loading: boolean }) => React.ReactNode;
}) {
const [isLoading, setIsLoading] = useSafeState(lazy && Math.abs(currentPage - index) > 0);

if (isLoading && Math.abs(currentPage - index) <= 0 && lazy) {
setIsLoading(false);
}

useEffect(() => {
let timer: NodeJS.Timeout | undefined;

if (!lazy && isLoading) {
timer = setTimeout(() => {
setIsLoading(false);
}, 0);
}

return () => {
clearTimeout(timer);
};
}, [lazy, isLoading]);

const focused = currentPage === index;

return (
<View
accessibilityElementsHidden={!focused}
importantForAccessibility={focused ? 'auto' : 'no-hide-descendants'}
style={{
flex: 1,
overflow: 'hidden',
}}
>
{children({ loading: isLoading })}
</View>
);
}
2 changes: 2 additions & 0 deletions packages/react-native-tabs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ return (
| tabItemStyle | `false` | 选项卡标签样式 | `ViewStyle` | |
| labelStyle | `false` | 标签文字样式 | `TextStyle` | |
| indicatorStyle | `false` | 指示器样式 | `ViewStyle` | |
| lazy | `false` | 是否启用懒加载模式 | `boolean` | |
| lazyPlaceholder | `false` | 懒加载时的placeholder组件 | `() => ReactNode` | |

```ts
interface TabScene {
Expand Down
23 changes: 20 additions & 3 deletions packages/react-native-tabs/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { cloneElement } from 'react';
import { ComponentType, createElement, memo } from 'react';
import { Animated, StyleProp, TextStyle, ViewStyle } from 'react-native';
import PagerView from 'react-native-pager-view';

import { Box, helpers } from '@td-design/react-native';

import SceneView from './SceneView';
import ScrollBar from './ScrollBar';
import TabBar from './TabBar';
import usePagerView from './usePagerView';
Expand All @@ -13,11 +14,13 @@ const AnimatedPagerView = Animated.createAnimatedComponent<typeof PagerView>(Pag

type Tab = {
title: string;
component: JSX.Element;
component: ComponentType<any>;
};

export interface TabsProps {
scenes: Tab[];
lazy?: boolean;
renderLazyPlaceholder?: () => JSX.Element;
/** 默认当前是第几个tab */
initialPage?: number;
/** 当前是第几个tab */
Expand All @@ -42,6 +45,8 @@ export interface TabsProps {

export default function Tabs({
initialPage = 0,
lazy = false,
renderLazyPlaceholder,
page,
onChange,
scenes = [],
Expand Down Expand Up @@ -103,8 +108,20 @@ export default function Tabs({
onPageSelected={onPageSelected}
onPageScrollStateChanged={onPageScrollStateChanged}
>
{scenes.map(({ title, component }) => cloneElement(component, { key: title }))}
{scenes.map(({ component }, i) => (
<SceneView key={i} index={i} lazy={lazy} currentPage={currentPage}>
{({ loading }) => {
if (loading) return renderLazyPlaceholder?.();

return <SceneComponent {...{ component }} />;
}}
</SceneView>
))}
</AnimatedPagerView>
</Box>
);
}

const SceneComponent = memo(<T extends { component: ComponentType<any> }>({ component }: T) => {
return createElement(component);
});
14 changes: 14 additions & 0 deletions packages/react-native-tabs/src/types.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export type Route = {
key: string;
icon?: string;
title?: string;
};

export type Scene<T extends Route> = {
route: T;
};

export type NavigationState<T extends Route> = {
index: number;
routes: T[];
};

0 comments on commit 273401f

Please sign in to comment.