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 => {