Skip to content

Commit 91a23e0

Browse files
committed
revised
1 parent bcbba7e commit 91a23e0

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

packages/svelte/src/internal/client/runtime.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,12 @@ export function update_reaction(reaction) {
418418
skip_reaction =
419419
(flags & UNOWNED) !== 0 &&
420420
(!is_flushing_effect ||
421+
// If we were previously not in a reactive context and we're reading an unowned derived
422+
// that was created inside another derived, then we don't fully know the real owner and thus
423+
// we need to skip adding any reactions for this unowned
424+
((previous_reaction === null || previous_untracking) &&
421425
(/** @type {Derived} */ (reaction).parent !== null &&
422-
(/** @type {Derived} */ (reaction).parent.f & DERIVED) !== 0));
426+
(/** @type {Derived} */ (reaction).parent.f & DERIVED) !== 0)));
423427

424428
derived_sources = null;
425429
set_component_context(reaction.ctx);

packages/svelte/tests/signals/test.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ describe('signals', () => {
6969
};
7070
});
7171

72-
test('multiple effects with state and derived in it#1', () => {
72+
test('multiple effects with state and derived in it #1', () => {
7373
const log: string[] = [];
7474

7575
let count = state(0);
@@ -90,7 +90,7 @@ describe('signals', () => {
9090
};
9191
});
9292

93-
test('multiple effects with state and derived in it#2', () => {
93+
test('multiple effects with state and derived in it #2', () => {
9494
const log: string[] = [];
9595

9696
let count = state(0);
@@ -596,6 +596,46 @@ describe('signals', () => {
596596
};
597597
});
598598

599+
test('mixed nested deriveds correctly cleanup when no longer connected to graph #3', () => {
600+
let a: Derived<unknown>;
601+
let b: Derived<unknown>;
602+
let s = state(0);
603+
let logs: any[] = [];
604+
605+
const destroy = effect_root(() => {
606+
render_effect(() => {
607+
a = derived(() => {
608+
b = derived(() => {
609+
return $.get(s);
610+
});
611+
effect_root(() => {
612+
$.get(b);
613+
});
614+
render_effect(() => {
615+
debugger
616+
logs.push($.get(b));
617+
});
618+
$.get(s);
619+
});
620+
$.get(a);
621+
});
622+
});
623+
624+
return () => {
625+
flushSync();
626+
assert.equal(a?.deps?.length, 1);
627+
assert.equal(s?.reactions?.length, 2);
628+
629+
set(s, 1);
630+
flushSync();
631+
632+
assert.deepEqual(logs, [0, 1]);
633+
634+
destroy();
635+
assert.equal(s?.reactions, null);
636+
};
637+
});
638+
599639
test('deriveds update upon reconnection #1', () => {
600640
let a = state(false);
601641
let b = state(false);

0 commit comments

Comments
 (0)