From ec17ad5805266411d660e83db35a8fdd603bb8ff Mon Sep 17 00:00:00 2001 From: Brandon Presley Date: Wed, 15 Nov 2023 11:29:40 +1300 Subject: [PATCH] Wrap SetItem in React.memo Apparently large lists in React Native should be wrapped in this, as long as they don't have any internal state. So this should theoretically improve performance when you scroll down a lot. --- SetItem.tsx | 137 +++++++++++++++++++++++++++------------------------- 1 file changed, 71 insertions(+), 66 deletions(-) diff --git a/SetItem.tsx b/SetItem.tsx index 4d0cca8..ebc1f97 100644 --- a/SetItem.tsx +++ b/SetItem.tsx @@ -1,6 +1,6 @@ import { NavigationProp, useNavigation } from "@react-navigation/native"; import { format } from "date-fns"; -import { useCallback, useMemo } from "react"; +import React, { useCallback, useMemo } from "react"; import { Image } from "react-native"; import { List, Text, useTheme } from "react-native-paper"; import { StackParams } from "./AppStack"; @@ -8,74 +8,79 @@ import { DARK_RIPPLE, LIGHT_RIPPLE } from "./constants"; import GymSet from "./gym-set"; import Settings from "./settings"; -export default function SetItem({ - item, - settings, - ids, - setIds, - disablePress, - customBg, -}: { - item: GymSet; - settings: Settings; - ids: number[]; - setIds: (value: number[]) => void; - disablePress?: boolean; - customBg?: string; -}) { - const { dark } = useTheme(); - const navigation = useNavigation>(); +const SetItem = React.memo( + ({ + item, + settings, + ids, + setIds, + disablePress, + customBg, + }: { + item: GymSet; + settings: Settings; + ids: number[]; + setIds: (value: number[]) => void; + disablePress?: boolean; + customBg?: string; + }) => { + const { dark } = useTheme(); + const navigation = useNavigation>(); - const longPress = useCallback(() => { - if (ids.length > 0) return; - setIds([item.id]); - }, [ids.length, item.id, setIds]); + const longPress = useCallback(() => { + if (ids.length > 0) return; + setIds([item.id]); + }, [ids.length, item.id, setIds]); - const press = useCallback(() => { - if (disablePress) return; - if (ids.length === 0) return navigation.navigate("EditSet", { set: item }); - const removing = ids.find((id) => id === item.id); - if (removing) setIds(ids.filter((id) => id !== item.id)); - else setIds([...ids, item.id]); - }, [ids, item, navigation, setIds, disablePress]); + const press = useCallback(() => { + if (disablePress) return; + if (ids.length === 0) + return navigation.navigate("EditSet", { set: item }); + const removing = ids.find((id) => id === item.id); + if (removing) setIds(ids.filter((id) => id !== item.id)); + else setIds([...ids, item.id]); + }, [ids, item, navigation, setIds, disablePress]); - const backgroundColor = useMemo(() => { - if (!ids.includes(item.id)) return; - if (dark) return DARK_RIPPLE; - return LIGHT_RIPPLE; - }, [dark, ids, item.id]); + const backgroundColor = useMemo(() => { + if (!ids.includes(item.id)) return; + if (dark) return DARK_RIPPLE; + return LIGHT_RIPPLE; + }, [dark, ids, item.id]); + + const image = useCallback(() => { + if (!settings.images || !item.image) return null; + return ( + + ); + }, [item.image, settings.images]); - const image = useCallback(() => { - if (!settings.images || !item.image) return null; return ( - - ); - }, [item.image, settings.images]); - - return ( - - {format(new Date(item.created), settings.date || "P")} + + {format(new Date(item.created), settings.date || "P")} + + ) : null + } + onLongPress={longPress} + style={{ backgroundColor: customBg || backgroundColor }} + left={image} + right={() => ( + + {`${item.reps} x ${item.weight}${item.unit || "kg"}`} - ) : null - } - onLongPress={longPress} - style={{ backgroundColor: customBg || backgroundColor }} - left={image} - right={() => ( - - {`${item.reps} x ${item.weight}${item.unit || "kg"}`} - - )} - /> - ); -} + )} + /> + ); + } +); + +export default SetItem;