From eb4d1950edf9f5f4405be6a490519defdc05c9f7 Mon Sep 17 00:00:00 2001 From: Anton Arnautov Date: Sun, 8 Dec 2024 12:28:59 +0100 Subject: [PATCH] Check individual selected values --- src/store/hooks/useStateStore.ts | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/store/hooks/useStateStore.ts b/src/store/hooks/useStateStore.ts index fab11df11..44b1f7fd7 100644 --- a/src/store/hooks/useStateStore.ts +++ b/src/store/hooks/useStateStore.ts @@ -26,18 +26,35 @@ export function useStateStore< ); const wrappedSnapshot = useMemo(() => { - let cached: [T, O]; + let cachedTuple: [T, O]; + return () => { - const current = store?.getLatestValue(); + const currentValue = store?.getLatestValue(); + + if (!currentValue) return undefined; + + // store value hasn't changed, no need to compare individual values + if (cachedTuple && cachedTuple[0] === currentValue) { + return cachedTuple[1]; + } + + const newlySelected = selector(currentValue); + + // store value changed but selected values wouldn't have to, double-check selected + if (cachedTuple) { + let selectededAreEqualToCached = true; - if (!current) return undefined; + for (const key in cachedTuple[1]) { + if (cachedTuple[1][key] === newlySelected[key]) continue; + selectededAreEqualToCached = false; + break; + } - if (!cached || cached[0] !== current) { - cached = [current, selector(current)]; - return cached[1]; + if (selectededAreEqualToCached) return cachedTuple[1]; } - return cached[1]; + cachedTuple = [currentValue, newlySelected]; + return cachedTuple[1]; }; }, [store, selector]);