From 990d371d4e424d23f24baa70ac6575a2e2b4aa13 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Sun, 31 May 2026 09:01:50 -0700 Subject: [PATCH] perf: move pair confirm cleanup to root ref --- mobile/app/pair-confirm.tsx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/mobile/app/pair-confirm.tsx b/mobile/app/pair-confirm.tsx index 6e28b2fd4..8e95ea438 100644 --- a/mobile/app/pair-confirm.tsx +++ b/mobile/app/pair-confirm.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef, useState } from 'react' +import { useCallback, useRef, useState } from 'react' import { View, Text, StyleSheet, Pressable, ActivityIndicator, BackHandler } from 'react-native' import { useSafeAreaInsets } from 'react-native-safe-area-context' import { useFocusEffect, useLocalSearchParams, useRouter } from 'expo-router' @@ -60,12 +60,16 @@ export default function PairConfirmScreen() { }, [cancel]) ) - useEffect(() => { - return () => { - mountedRef.current = false - activePairingAttemptRef.current?.dispose() - activePairingAttemptRef.current = null + const setPairConfirmRootRef = useCallback((node: View | null): void => { + if (node !== null) { + mountedRef.current = true + return } + // Why: pairing attempts can outlive the visible route; dispose them when + // the confirm screen detaches without a passive cleanup-only Effect. + mountedRef.current = false + activePairingAttemptRef.current?.dispose() + activePairingAttemptRef.current = null }, []) async function confirm() { @@ -155,7 +159,7 @@ export default function PairConfirmScreen() { const containerPadding = { paddingTop: insets.top + spacing.sm } return ( - +