diff --git a/packages/react/src/hooks/useAtomInstance.ts b/packages/react/src/hooks/useAtomInstance.ts index 1d573df4..d2c38812 100644 --- a/packages/react/src/hooks/useAtomInstance.ts +++ b/packages/react/src/hooks/useAtomInstance.ts @@ -117,13 +117,17 @@ export const useAtomInstance: { if (edge) { let prevEdge = edge.prevEdge?.deref() + edge.isMaterialized = true + // clear out any junk edges added by StrictMode while (prevEdge && !prevEdge.isMaterialized) { ecosystem._graph.removeEdge(prevEdge.dependentKey!, instance.id) + + // mark in case of circular references (shouldn't happen, but just for + // consistency with the prevCache algorithm) + prevEdge.isMaterialized = true prevEdge = prevEdge.prevEdge?.deref() } - - edge.isMaterialized = true } // Try adding the edge again (will be a no-op unless React's StrictMode ran diff --git a/packages/react/src/hooks/useAtomSelector.ts b/packages/react/src/hooks/useAtomSelector.ts index 4c1c4541..46b3ebc2 100644 --- a/packages/react/src/hooks/useAtomSelector.ts +++ b/packages/react/src/hooks/useAtomSelector.ts @@ -93,7 +93,7 @@ export const useAtomSelector = ( cache._lastEdge = new WeakRef(edge) } - if (selectors._lastCache && selectors._lastCache.deref() !== cache) { + if (selectors._lastCache) { cache._prevCache = selectors._lastCache } @@ -115,25 +115,33 @@ export const useAtomSelector = ( if (edge) { let prevEdge = edge.prevEdge?.deref() + edge.isMaterialized = true + // clear out any junk edges added by StrictMode while (prevEdge && !prevEdge.isMaterialized) { ecosystem._graph.removeEdge(prevEdge.dependentKey!, cache.id) + + // mark in case of circular references (shouldn't happen, but just for + // consistency with the prevCache algorithm) + prevEdge.isMaterialized = true prevEdge = prevEdge.prevEdge?.deref() } - - edge.isMaterialized = true } let prevCache = cache._prevCache?.deref() + cache.isMaterialized = true + // clear out any junk caches created by StrictMode while (prevCache && !prevCache.isMaterialized) { selectors.destroyCache(prevCache, [], true) + + // mark in case of circular references (can happen in certain React + // rendering sequences) + prevCache.isMaterialized = true prevCache = prevCache._prevCache?.deref() } - cache.isMaterialized = true - // Try adding the edge again (will be a no-op unless React's StrictMode ran // this effect's cleanup unnecessarily) addEdge()