diff --git a/src/vanilla/store.ts b/src/vanilla/store.ts index d2f7bcc2a2..bde30f57d4 100644 --- a/src/vanilla/store.ts +++ b/src/vanilla/store.ts @@ -368,9 +368,17 @@ export const createStore = () => { // Otherwise, check if the dependencies have changed. // If all dependencies haven't changed, we can use the cache. if ( - Array.from(atomState.d).every( - ([a, s]) => a === atom || readAtomState(a) === s - ) + Array.from(atomState.d).every(([a, s]) => { + if (a === atom) { + return true + } + const aState = readAtomState(a) + return ( + aState === s || + // We need to check values in case only dependencies are changed + (aState && isEqualAtomValue(aState, s)) + ) + }) ) { return atomState } diff --git a/tests/vanilla/store.test.tsx b/tests/vanilla/store.test.tsx index a95d35b12a..6093439d74 100644 --- a/tests/vanilla/store.test.tsx +++ b/tests/vanilla/store.test.tsx @@ -423,3 +423,15 @@ it('should update derived atoms during write (#2107)', async () => { store.set(countAtom, 2) expect(store.get(countAtom)).toBe(2) }) + +it('should not recompute a derived atom value if unchanged (#2168)', async () => { + const store = createStore() + const countAtom = atom(1) + const derived1Atom = atom((get) => get(countAtom) * 0) + const derive2Fn = vi.fn((get: Getter) => get(derived1Atom)) + const derived2Atom = atom(derive2Fn) + expect(store.get(derived2Atom)).toBe(0) + store.set(countAtom, (c) => c + 1) + expect(store.get(derived2Atom)).toBe(0) + expect(derive2Fn).toHaveBeenCalledTimes(1) +})