Skip to content

Commit 644ba5e

Browse files
dmaskaskydai-shi
andauthored
fix(store): recompute dependents on eager evaluation in writeAtomState (#2965)
* add failing test * fix the test * only recompute the atom we are getting * include dirty dependencies (deep) * only recompute if the top is dirty * beautify * alternate solution --------- Co-authored-by: daishi <[email protected]>
1 parent bcf45c9 commit 644ba5e

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

src/vanilla/store.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
389389
return setSelf
390390
},
391391
}
392+
const prevEpochNumber = atomState.n
392393
try {
393394
const valueOrPromise = atomRead(atom, getter, options as never)
394395
setAtomStateValueOrPromise(atom, atomState, valueOrPromise)
@@ -404,6 +405,14 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
404405
return atomState
405406
} finally {
406407
isSync = false
408+
if (
409+
prevEpochNumber !== atomState.n &&
410+
invalidatedAtoms.get(atom) === prevEpochNumber
411+
) {
412+
invalidatedAtoms.set(atom, atomState.n)
413+
changedAtoms.set(atom, atomState)
414+
atomState.u?.()
415+
}
407416
}
408417
}
409418

tests/vanilla/store.test.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,3 +1223,22 @@ it('updates with reading derived atoms (#2959)', () => {
12231223
store.set(countUpAtom)
12241224
expect(store.get(countDerivedAtom)).toBe(2)
12251225
})
1226+
1227+
it('updates dependents when it eagerly recomputes dirty atoms', () => {
1228+
const countAtom = atom(0)
1229+
const isActiveAtom = atom(false)
1230+
const activeCountAtom = atom((get) =>
1231+
get(isActiveAtom) ? get(countAtom) : undefined,
1232+
)
1233+
const activateAction = atom(null, (get, set, value: boolean) => {
1234+
set(isActiveAtom, value)
1235+
get(activeCountAtom)
1236+
})
1237+
1238+
const store = createStore()
1239+
store.sub(activeCountAtom, () => {})
1240+
store.set(activateAction, true)
1241+
store.set(countAtom, 1)
1242+
1243+
expect(store.get(activeCountAtom)).toBe(1)
1244+
})

0 commit comments

Comments
 (0)