Skip to content

Commit

Permalink
fix(reactivity): ensure computed is invalidated before other effects
Browse files Browse the repository at this point in the history
fix #5720
  • Loading branch information
yyx990803 committed Apr 15, 2022
1 parent 56879e6 commit 82bdf86
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 10 deletions.
17 changes: 17 additions & 0 deletions packages/reactivity/__tests__/computed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,23 @@ describe('reactivity/computed', () => {
expect(dummy).toBe(-1)
})

// #5720
it('should invalidate before non-computed effects', () => {
let plusOneValues: number[] = []
const n = ref(0)
const plusOne = computed(() => n.value + 1)
effect(() => {
n.value
plusOneValues.push(plusOne.value)
})
// access plusOne, causing it to be non-dirty
plusOne.value
// mutate n
n.value++
// on the 2nd run, plusOne.value should have already updated.
expect(plusOneValues).toMatchObject([1, 2, 2])
})

it('should warn if trying to set a readonly computed', () => {
const n = ref(1)
const plusOne = computed(() => n.value + 1)
Expand Down
35 changes: 25 additions & 10 deletions packages/reactivity/src/effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,16 +348,31 @@ export function triggerEffects(
debuggerEventExtraInfo?: DebuggerEventExtraInfo
) {
// spread into array for stabilization
for (const effect of isArray(dep) ? dep : [...dep]) {
if (effect !== activeEffect || effect.allowRecurse) {
if (__DEV__ && effect.onTrigger) {
effect.onTrigger(extend({ effect }, debuggerEventExtraInfo))
}
if (effect.scheduler) {
effect.scheduler()
} else {
effect.run()
}
const effects = isArray(dep) ? dep : [...dep]
for (const effect of effects) {
if (effect.computed) {
triggerEffect(effect, debuggerEventExtraInfo)
}
}
for (const effect of effects) {
if (!effect.computed) {
triggerEffect(effect, debuggerEventExtraInfo)
}
}
}

function triggerEffect(
effect: ReactiveEffect,
debuggerEventExtraInfo?: DebuggerEventExtraInfo
) {
if (effect !== activeEffect || effect.allowRecurse) {
if (__DEV__ && effect.onTrigger) {
effect.onTrigger(extend({ effect }, debuggerEventExtraInfo))
}
if (effect.scheduler) {
effect.scheduler()
} else {
effect.run()
}
}
}

0 comments on commit 82bdf86

Please sign in to comment.