diff --git a/fixture/react-native/src/ComplexMasonry.tsx b/fixture/react-native/src/ComplexMasonry.tsx index 58872130e..710f90082 100644 --- a/fixture/react-native/src/ComplexMasonry.tsx +++ b/fixture/react-native/src/ComplexMasonry.tsx @@ -1,4 +1,11 @@ -import React, { forwardRef, ForwardedRef, useState, useCallback } from "react"; +import React, { + forwardRef, + ForwardedRef, + useState, + useCallback, + useEffect, + useRef, +} from "react"; import { Text, View, @@ -6,6 +13,7 @@ import { Platform, TouchableOpacity, ActivityIndicator, + useWindowDimensions, } from "react-native"; import { FlashListRef, FlashList } from "@shopify/flash-list"; import FastImage from "@d11/react-native-fast-image"; @@ -132,9 +140,21 @@ const MasonryCard = ({ // Create our masonry component const ComplexMasonryComponent = (_: unknown, ref: ForwardedRef) => { + const { height } = useWindowDimensions(); const columnCount = 3; const [items, setItems] = useState(() => generateMasonryData(50)); const [isLoading, setIsLoading] = useState(false); + const loadTimeout = useRef | null>(null); + + useEffect( + () => () => { + if (loadTimeout.current !== null) { + clearTimeout(loadTimeout.current); + loadTimeout.current = null; + } + }, + [] + ); // Handle toggling the expanded state of an item const handleToggleExpand = useCallback((id: string) => { @@ -147,19 +167,20 @@ const ComplexMasonryComponent = (_: unknown, ref: ForwardedRef) => { // Handle loading more items when reaching the end of the list const handleEndReached = useCallback(() => { - if (isLoading) return; + if (loadTimeout.current !== null) return; setIsLoading(true); // Simulate network delay - setTimeout(() => { + loadTimeout.current = setTimeout(() => { + loadTimeout.current = null; setItems((currentItems) => [ ...currentItems, ...generateMasonryData(20, currentItems.length), ]); setIsLoading(false); }, 500); - }, [isLoading]); + }, []); // Footer component with loading indicator const renderFooter = useCallback(() => { @@ -180,7 +201,7 @@ const ComplexMasonryComponent = (_: unknown, ref: ForwardedRef) => { ); return ( - + >} testID="ComplexMasonryList" @@ -218,7 +239,6 @@ export const ComplexMasonry = forwardRef(ComplexMasonryComponent); const styles = StyleSheet.create({ container: { flex: Platform.OS === "web" ? undefined : 1, - height: Platform.OS === "web" ? window.innerHeight : undefined, backgroundColor: "#f5f5f5", }, listContent: { diff --git a/fixture/react-native/src/DynamicColumnSpan.tsx b/fixture/react-native/src/DynamicColumnSpan.tsx index bd74ab4dc..61a865b0e 100644 --- a/fixture/react-native/src/DynamicColumnSpan.tsx +++ b/fixture/react-native/src/DynamicColumnSpan.tsx @@ -1,5 +1,12 @@ import React, { useMemo, useState, useCallback } from "react"; -import { Text, View, StyleSheet, Platform, Pressable } from "react-native"; +import { + Text, + View, + StyleSheet, + Platform, + Pressable, + useWindowDimensions, +} from "react-native"; import { FlashList, useRecyclingState } from "@shopify/flash-list"; interface DynamicItem { @@ -53,6 +60,7 @@ const arraysEqual = (arr1: number[], arr2: number[]): boolean => { }; export function DynamicColumnSpan() { + const { height } = useWindowDimensions(); const [numItems] = useState(500); const [isMasonry, setIsMasonry] = useState(false); const [numColumns, setNumColumns] = useState(3); @@ -101,10 +109,6 @@ export function DynamicColumnSpan() { [] ); - const toggleLayout = () => { - setIsMasonry(!isMasonry); - }; - const changeColumns = (cols: number) => { setNumColumns(cols); }; @@ -115,14 +119,14 @@ export function DynamicColumnSpan() { return ( - + {/* Control Panel */} Layout: setIsMasonry(false)} > setIsMasonry(true)} > { }; export function Grid() { + const { height } = useWindowDimensions(); const [numItems] = useState(1000); // Default to 100 items // Generate colors for the grid items @@ -69,7 +77,7 @@ export function Grid() { return ( - + { const styles = StyleSheet.create({ container: { flex: Platform.OS === "web" ? undefined : 1, - height: Platform.OS === "web" ? window.innerHeight : undefined, backgroundColor: "#f5f5f5", }, itemWrapper: { diff --git a/fixture/react-native/src/LayoutOptions.tsx b/fixture/react-native/src/LayoutOptions.tsx index 9224a1992..f5cee233b 100644 --- a/fixture/react-native/src/LayoutOptions.tsx +++ b/fixture/react-native/src/LayoutOptions.tsx @@ -7,6 +7,7 @@ import { Pressable, Switch, ScrollView, + useWindowDimensions, } from "react-native"; import { FlashList, useRecyclingState } from "@shopify/flash-list"; @@ -38,6 +39,7 @@ const colors = [ ]; export function LayoutOptions() { + const { height } = useWindowDimensions(); // Configuration states const [numColumns, setNumColumns] = useState(1); const [isHorizontal, setIsHorizontal] = useState(false); @@ -88,10 +90,11 @@ export function LayoutOptions() { }, []); return ( - + {renderControls()} { const styles = StyleSheet.create({ container: { flex: Platform.OS === "web" ? undefined : 1, - height: Platform.OS === "web" ? window.innerHeight : undefined, backgroundColor: "#f5f5f5", }, controls: { diff --git a/fixture/react-native/src/Masonry.tsx b/fixture/react-native/src/Masonry.tsx index 737144d31..1980972bc 100644 --- a/fixture/react-native/src/Masonry.tsx +++ b/fixture/react-native/src/Masonry.tsx @@ -1,5 +1,11 @@ import React from "react"; -import { Text, View, StyleSheet, Platform } from "react-native"; +import { + Text, + View, + StyleSheet, + Platform, + useWindowDimensions, +} from "react-native"; import { FlashList } from "@shopify/flash-list"; interface MasonryData { @@ -8,6 +14,7 @@ interface MasonryData { } export function Masonry() { + const { height } = useWindowDimensions(); const columnCount = 3; const data: MasonryData[] = new Array(999).fill(null).map((_, index) => { return { @@ -17,7 +24,7 @@ export function Masonry() { }); return ( - + { }; export function Grid() { + const { height } = useWindowDimensions(); const [numItems] = useState(1000); // Default to 100 items // Generate colors for the grid items @@ -68,8 +76,8 @@ export function Grid() { const keyExtractor = useCallback((item: GridItem) => item.id.toString(), []); return ( - - + { const styles = StyleSheet.create({ container: { flex: Platform.OS === "web" ? undefined : 1, - height: Platform.OS === "web" ? window.innerHeight : undefined, backgroundColor: "#f5f5f5", }, itemWrapper: {