Skip to content

Commit

Permalink
fix(reactivity): fix effect not schedule when trigger maybedirty
Browse files Browse the repository at this point in the history
close #11236
  • Loading branch information
Doctor-wu committed Jun 27, 2024
1 parent 261fb7c commit 5d52d19
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 9 deletions.
34 changes: 34 additions & 0 deletions packages/reactivity/__tests__/computed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,40 @@ describe('reactivity/computed', () => {
expect(COMPUTED_SIDE_EFFECT_WARN).toHaveBeenWarned()
})

// #11236
it('should schedule effect when trigger maybedirty', async () => {
const foo = ref<any>({})

const bar = computed(() => {
foo.value.bar ??= {}
return foo.value.bar
})

const baz = computed(() => {
bar.value.baz ??= []
return bar.value.baz
})

const qux = computed(() => baz.value.at(-1) === 2)

const Comp = {
render: () => h('div', [JSON.stringify(qux.value)]),
}
const root = nodeOps.createElement('div')
render(h(Comp), root)
await nextTick()
expect(serializeInner(root)).toBe('<div>false</div>')

baz.value.push(1)
await nextTick()
expect(serializeInner(root)).toBe('<div>false</div>')

baz.value.push(2)
await nextTick()
expect(serializeInner(root)).toBe('<div>true</div>')
expect(COMPUTED_SIDE_EFFECT_WARN).toHaveBeenWarned()
})

it('debug: onTrigger (ref)', () => {
let events: DebuggerEvent[] = []
const onTrigger = vi.fn((e: DebuggerEvent) => {
Expand Down
28 changes: 19 additions & 9 deletions packages/reactivity/src/effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,15 +325,7 @@ export function triggerEffects(
effect._dirtyLevel < dirtyLevel &&
(tracking ??= dep.get(effect) === effect._trackId)
) {
effect._shouldSchedule ||= effect._dirtyLevel === DirtyLevels.NotDirty
// always schedule if the computed is original side effect
// since we know it is actually dirty
if (
effect.computed &&
effect._dirtyLevel === DirtyLevels.MaybeDirty_ComputedSideEffect_Origin
) {
effect._shouldSchedule = true
}
resolveSchedule(effect, dirtyLevel)
effect._dirtyLevel = dirtyLevel
}
if (
Expand All @@ -358,3 +350,21 @@ export function triggerEffects(
}
resetScheduling()
}

function resolveSchedule(effect: ReactiveEffect, dirtyLevel: DirtyLevels) {
effect._shouldSchedule ||= effect._dirtyLevel === DirtyLevels.NotDirty
// always schedule if the computed is original side effect
// since we know it is actually dirty
if (
effect.computed &&
effect._dirtyLevel === DirtyLevels.MaybeDirty_ComputedSideEffect_Origin
) {
effect._shouldSchedule = true
}
if (
effect._dirtyLevel === DirtyLevels.MaybeDirty_ComputedSideEffect &&
dirtyLevel > DirtyLevels.MaybeDirty_ComputedSideEffect
) {
effect._shouldSchedule = true
}
}

0 comments on commit 5d52d19

Please sign in to comment.