diff --git a/app/(tabs)/generate.tsx b/app/(tabs)/generate.tsx index e9704d9..69aa29a 100644 --- a/app/(tabs)/generate.tsx +++ b/app/(tabs)/generate.tsx @@ -1,4 +1,5 @@ import { FontAwesome, Fontisto, Ionicons } from '@expo/vector-icons' +import { useIsFocused } from '@react-navigation/native' import { FlashList } from '@shopify/flash-list' import { useFocusEffect, useRouter } from 'expo-router' import { observer } from 'mobx-react-lite' @@ -42,8 +43,11 @@ const Generate = observer(function Generate() { const templates = useTemplates() const { runTemplate } = useTemplateActions() + // 直接使用 useIsFocused hook,页面失焦时不渲染列表项以减少内存占用 + const isFocused = useIsFocused() + useFocusEffect(() => { - if (!isAuthenticated) { + if (!isAuthenticated && isFocused) { router.replace('/') router.push('/auth') } @@ -253,11 +257,13 @@ const Generate = observer(function Generate() { item={item} key={item?.id} itemWidth={itemWidth} + // 页面失焦时不渲染,减少内存占用 + isVisible={isFocused} onSelect={() => handleSelectTemplate(item)} /> ) }, - [selectedTemplateId, itemWidth, handleSelectTemplate], + [selectedTemplateId, itemWidth, handleSelectTemplate, isFocused], ) const ListHeader = useMemo(() => { @@ -457,9 +463,16 @@ type TemplateItemProps = { item: Template itemWidth: number isSelected: boolean + isVisible?: boolean onSelect: () => void } -const TemplateItem = memo(function TemplateItem({ item, itemWidth, isSelected, onSelect }) { +const TemplateItem = memo(function TemplateItem({ + item, + itemWidth, + isSelected, + isVisible = true, + onSelect, +}) { return ( (function TemplateItem({ item, itemW onClick={onSelect} > {/* */} - + {isVisible && } {isSelected && } {isSelected && } diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index bed78bc..a4429cf 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -1,4 +1,5 @@ import { Ionicons } from '@expo/vector-icons' +import { useIsFocused } from '@react-navigation/native' import { Block, ConfirmModal, Img, ListEmpty, Text, Toast, VideoBox } from '@share/components' import { FlashList } from '@shopify/flash-list' import { LinearGradient } from 'expo-linear-gradient' @@ -54,6 +55,9 @@ const Index = observer(function Index() { const [allItems, setAllItems] = useState([]) const [selectedItem, setSelectedItem] = useState(null) + // 直接使用 useIsFocused hook,无需手动管理状态 + const isFocused = useIsFocused() + const [refreshing, setRefreshing] = useState(false) const [loadingMore, setLoadingMore] = useState(false) const [hasMore, setHasMore] = useState(true) @@ -391,11 +395,12 @@ const Index = observer(function Index() { isSelected={selectedId === item.id} item={item} itemWidth={ITEM_WIDTH} - isVisible={index < 9 || visibleIdsRef.current.has(item.id)} + // 页面失焦时不渲染,减少内存占用 + isVisible={isFocused && (index < 9 || visibleIdsRef.current.has(item.id))} onSelect={() => setSelectedItem(item)} /> ), - [selectedId], + [selectedId, isFocused], ) const keyExtractor = useCallback((item: MediaItem) => item.id, []) diff --git a/app/(tabs)/sync.tsx b/app/(tabs)/sync.tsx index 61513f0..3ecc429 100644 --- a/app/(tabs)/sync.tsx +++ b/app/(tabs)/sync.tsx @@ -1,4 +1,5 @@ import { AntDesign, EvilIcons, FontAwesome, Ionicons, MaterialCommunityIcons } from '@expo/vector-icons' +import { useIsFocused } from '@react-navigation/native' import { Block, ConfirmModal, Img, Input, ListEmpty, Text, Toast, VideoBox } from '@share/components' import { FlashList } from '@shopify/flash-list' import * as ImagePicker from 'expo-image-picker' @@ -47,6 +48,9 @@ const Sync = observer(() => { const [isSelectionMode, setIsSelectionMode] = useState(false) const [selectedIds, setSelectedIds] = useState>(new Set()) + // 直接使用 useIsFocused hook,页面失焦时不渲染列表项以减少内存占用 + const isFocused = useIsFocused() + const { connectedDevice, isScanning, transferProgress } = bleStore.state const itemWidth = Math.floor((screenWidth - 12 * 2 - 12 * 2) / 3) @@ -380,16 +384,18 @@ const Sync = observer(() => { isSelectionMode={isSelectionMode} itemWidth={itemWidth} post={post} + // 页面失焦时不渲染,减少内存占用 + isVisible={isFocused} onSelect={handleItemSelect} key={post?.id} /> ) }, - [isSelectionMode, selectedIds, selectedItem, itemWidth, handleItemSelect], + [isSelectionMode, selectedIds, selectedItem, itemWidth, handleItemSelect, isFocused], ) return ( - + @@ -658,12 +664,14 @@ const GridItem = memo( isSelected, isSelectionMode, itemWidth, + isVisible = true, onSelect, }: { post: any isSelected: boolean isSelectionMode: boolean itemWidth: number + isVisible?: boolean onSelect: (post: any) => void }) => { // 渲染状态标记 @@ -707,7 +715,7 @@ const GridItem = memo( style={{ transform: [{ skewX: '-6deg' }], height: itemWidth, width: itemWidth }} > - + {isVisible && } {isSelected && } diff --git a/components/BannerSection.tsx b/components/BannerSection.tsx index a292c6a..14f4f32 100644 --- a/components/BannerSection.tsx +++ b/components/BannerSection.tsx @@ -1,3 +1,4 @@ +import { useIsFocused } from '@react-navigation/native' import { memo, useEffect, useState } from 'react' import Svg, { Circle, Defs, Pattern, Rect } from 'react-native-svg' @@ -19,6 +20,9 @@ const BannerSection = memo(function Banner({ bgVideo }) { setBgurl(bgVideo) }, [bgVideo]) + const isFocused = useIsFocused() + if (!isFocused) return null + return ( {/* 使用较小的分辨率降低内存占用 */}