From d9b7a1b6c5a0c9ababd71c4d2def3a5027d4818f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 01:44:33 +0000 Subject: [PATCH] perf: stabilize callbacks for memoized list items in Phonebook and Password screens Co-authored-by: TargetMisser <52361977+TargetMisser@users.noreply.github.com> --- src/screens/PasswordScreen.tsx | 19 +++++++++---------- src/screens/PhonebookScreen.tsx | 5 +++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/screens/PasswordScreen.tsx b/src/screens/PasswordScreen.tsx index c5338f1..346b411 100644 --- a/src/screens/PasswordScreen.tsx +++ b/src/screens/PasswordScreen.tsx @@ -101,7 +101,7 @@ function PinOverlay({ onUnlock, onCancel, title }: { onUnlock: (pin: string) => } // ─── Password Row ───────────────────────────────────────────────────────────── -function PasswordRowComponent({ item, onEdit, onDelete }: { item: PasswordEntry; onEdit: () => void; onDelete: () => void }) { +function PasswordRowComponent({ item, onEdit, onDelete }: { item: PasswordEntry; onEdit: (item: PasswordEntry) => void; onDelete: (id: string) => void }) { const { colors } = useAppTheme(); const s = useMemo(() => makeRowStyles(colors), [colors]); const [revealed, setRevealed] = useState(false); @@ -120,10 +120,10 @@ function PasswordRowComponent({ item, onEdit, onDelete }: { item: PasswordEntry; {item.notes ? {item.notes} : null} - + onEdit(item)}> - + onDelete(item.id)}> @@ -255,6 +255,11 @@ export default function PasswordScreen() { return setPinMode(null)} />; } + // Performance optimization: stabilize renderItem callback to prevent cascading re-renders of memoized PasswordRow items + const renderItem = useCallback(({ item }: { item: PasswordEntry }) => ( + + ), [openEdit, deleteEntry]); + return ( {/* Toolbar */} @@ -284,13 +289,7 @@ export default function PasswordScreen() { item.id} - renderItem={({ item }) => ( - openEdit(item)} - onDelete={() => deleteEntry(item.id)} - /> - )} + renderItem={renderItem} contentContainerStyle={{ padding: 16, paddingBottom: 96 }} ListEmptyComponent={ diff --git a/src/screens/PhonebookScreen.tsx b/src/screens/PhonebookScreen.tsx index 1884348..28c1824 100644 --- a/src/screens/PhonebookScreen.tsx +++ b/src/screens/PhonebookScreen.tsx @@ -380,8 +380,9 @@ export default function PhonebookScreen() { }); }, []); - const openAdd = () => { setEditing(null); setModalVisible(true); }; - const openEdit = (c: Contact) => { setEditing(c); setModalVisible(true); }; + // Performance optimization: stabilize callbacks to prevent unnecessary ContactRow re-renders + const openAdd = useCallback(() => { setEditing(null); setModalVisible(true); }, []); + const openEdit = useCallback((c: Contact) => { setEditing(c); setModalVisible(true); }, []); // Filter const filtered = contacts.filter(c => {