Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/vanilla/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,10 +509,12 @@ export const createStore = (): Store => {
// Track what's changed, so that we can short circuit when possible
const changedAtoms = new Set<AnyAtom>([atom])
const isMarked = (a: AnyAtom) => markedAtoms.has(a)
const prevEpochNumbers: number[] = topsortedAtoms.map(
(a) => getAtomState(a).n,
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Let me add a commit to refactor something.

for (let i = topsortedAtoms.length - 1; i >= 0; --i) {
const a = topsortedAtoms[i]!
const aState = getAtomState(a)
const prevEpochNumber = aState.n
let hasChangedDeps = false
for (const dep of aState.d.keys()) {
if (dep !== a && changedAtoms.has(dep)) {
Expand All @@ -523,7 +525,7 @@ export const createStore = (): Store => {
if (hasChangedDeps) {
readAtomState(pending, a, isMarked)
mountDependencies(pending, a, aState)
if (prevEpochNumber !== aState.n) {
if (prevEpochNumbers[i] !== aState.n) {
addPendingAtom(pending, a, aState)
changedAtoms.add(a)
}
Expand Down
20 changes: 20 additions & 0 deletions tests/vanilla/store.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -572,3 +572,23 @@ it('Unmount an atom that is no longer dependent within a derived atom (#2658)',
store.set(condAtom, false)
expect(onUnmount).toHaveBeenCalledTimes(1)
})

it('should update derived atom even if dependances changed (#2697)', () => {
const primitiveAtom = atom<number | undefined>(undefined)
const derivedAtom = atom((get) => get(primitiveAtom))
const conditionalAtom = atom((get) => {
const base = get(primitiveAtom)
if (!base) return
return get(derivedAtom)
})

const store = createStore()
const onChangeDerived = vi.fn()

store.sub(derivedAtom, onChangeDerived)
store.sub(conditionalAtom, () => {})

expect(onChangeDerived).toHaveBeenCalledTimes(0)
store.set(primitiveAtom, 1)
expect(onChangeDerived).toHaveBeenCalledTimes(1)
})