Skip to content

Commit 4cd3564

Browse files
eryue0220dai-shi
andauthored
fix(vanilla): avoid re-computing unmounted derived atoms in an edge case (#2197)
* fix: store bug * fix to pass the test --------- Co-authored-by: daishi <[email protected]> Co-authored-by: Daishi Kato <[email protected]>
1 parent 6c9e030 commit 4cd3564

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

src/vanilla/store.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,17 @@ export const createStore = () => {
368368
// Otherwise, check if the dependencies have changed.
369369
// If all dependencies haven't changed, we can use the cache.
370370
if (
371-
Array.from(atomState.d).every(
372-
([a, s]) => a === atom || readAtomState(a) === s
373-
)
371+
Array.from(atomState.d).every(([a, s]) => {
372+
if (a === atom) {
373+
return true
374+
}
375+
const aState = readAtomState(a)
376+
return (
377+
aState === s ||
378+
// We need to check values in case only dependencies are changed
379+
(aState && isEqualAtomValue(aState, s))
380+
)
381+
})
374382
) {
375383
return atomState
376384
}

tests/vanilla/store.test.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -423,3 +423,15 @@ it('should update derived atoms during write (#2107)', async () => {
423423
store.set(countAtom, 2)
424424
expect(store.get(countAtom)).toBe(2)
425425
})
426+
427+
it('should not recompute a derived atom value if unchanged (#2168)', async () => {
428+
const store = createStore()
429+
const countAtom = atom(1)
430+
const derived1Atom = atom((get) => get(countAtom) * 0)
431+
const derive2Fn = vi.fn((get: Getter) => get(derived1Atom))
432+
const derived2Atom = atom(derive2Fn)
433+
expect(store.get(derived2Atom)).toBe(0)
434+
store.set(countAtom, (c) => c + 1)
435+
expect(store.get(derived2Atom)).toBe(0)
436+
expect(derive2Fn).toHaveBeenCalledTimes(1)
437+
})

0 commit comments

Comments
 (0)