From: Carlos Rodrigues Date: Fri, 12 Jan 2024 09:37:28 +0000 (+0000) Subject: fix(reactivity): re-run effect when is dirty in the X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fpikax%2Fcomputed_render_issue;p=thirdparty%2Fvuejs%2Fcore.git fix(reactivity): re-run effect when is dirty in the --- diff --git a/packages/reactivity/__tests__/computed.spec.ts b/packages/reactivity/__tests__/computed.spec.ts index f66935d4c8..546e466820 100644 --- a/packages/reactivity/__tests__/computed.spec.ts +++ b/packages/reactivity/__tests__/computed.spec.ts @@ -72,6 +72,21 @@ describe('reactivity/computed', () => { expect(c1.value).toBe(1) }) + it('should work when chained(ref+computed)', () => { + const value = ref(0) + const provider = computed(() => value.value + consumer.value) + const consumer = computed(() => { + value.value++ + return 'foo' + }) + expect(provider.value).toBe('1foo') + + value.value += 1 + expect(provider.value).toBe('3foo') + value.value += 1 + expect(provider.value).toBe('5foo') + }) + it('should trigger effect when chained', () => { const value = reactive({ foo: 0 }) const getter1 = vi.fn(() => value.foo) diff --git a/packages/reactivity/src/effect.ts b/packages/reactivity/src/effect.ts index 5ddf8e6f0a..1a92a73963 100644 --- a/packages/reactivity/src/effect.ts +++ b/packages/reactivity/src/effect.ts @@ -110,7 +110,12 @@ export class ReactiveEffect { activeEffect = this this._runnings++ preCleanupEffect(this) - return this.fn() + const r = this.fn() + // @ts-expect-error this has become dirty in the run + if (this._dirtyLevel === DirtyLevels.Dirty) { + return this.fn() + } + return r } finally { postCleanupEffect(this) this._runnings-- @@ -289,9 +294,17 @@ export function triggerEffects( debuggerEventExtraInfo?: DebuggerEventExtraInfo, ) { pauseScheduling() + const hasDepsRunning = activeEffect ? dep.has(activeEffect) : false for (const effect of dep.keys()) { if (!effect.allowRecurse && effect._runnings) { - continue + if (hasDepsRunning && effect !== activeEffect) { + // maybe this effect is actually recursive + if (effect.allowRecurse === undefined) { + effect.allowRecurse = true + } + } else { + continue + } } if ( effect._dirtyLevel < dirtyLevel &&