Skip to content

Commit b624380

Browse files
trueadmRich-Harris
andauthored
fix: ensure correct parent effect is associated with render effects (#13274)
* fix: ensure correct parent effect is associated with render effects * fix --------- Co-authored-by: Rich Harris <[email protected]>
1 parent eba64f7 commit b624380

File tree

6 files changed

+58
-6
lines changed

6 files changed

+58
-6
lines changed

.changeset/khaki-camels-punch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: ensure correct parent effect is associated with render effects

packages/svelte/src/internal/client/reactivity/effects.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,10 @@ export function user_effect(fn) {
201201

202202
if (defer) {
203203
var context = /** @type {ComponentContext} */ (component_context);
204-
(context.e ??= []).push(fn);
204+
(context.e ??= []).push({
205+
fn,
206+
parent: active_effect
207+
});
205208
} else {
206209
var signal = effect(fn);
207210
return signal;

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,11 +1050,18 @@ export function pop(component) {
10501050
if (component !== undefined) {
10511051
context_stack_item.x = component;
10521052
}
1053-
const effects = context_stack_item.e;
1054-
if (effects !== null) {
1053+
const component_effects = context_stack_item.e;
1054+
if (component_effects !== null) {
1055+
var previous_effect = active_effect;
10551056
context_stack_item.e = null;
1056-
for (var i = 0; i < effects.length; i++) {
1057-
effect(effects[i]);
1057+
try {
1058+
for (var i = 0; i < component_effects.length; i++) {
1059+
var component_effect = component_effects[i];
1060+
set_active_effect(component_effect.parent);
1061+
effect(component_effect.fn);
1062+
}
1063+
} finally {
1064+
set_active_effect(previous_effect);
10581065
}
10591066
}
10601067
component_context = context_stack_item.p;

packages/svelte/src/internal/client/types.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export type ComponentContext = {
1515
/** context */
1616
c: null | Map<unknown, unknown>;
1717
/** deferred effects */
18-
e: null | Array<() => void | (() => void)>;
18+
e: null | Array<{ fn: () => void | (() => void); parent: null | Effect }>;
1919
/** mounted */
2020
m: boolean;
2121
/**
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { test } from '../../test';
2+
import { flushSync } from 'svelte';
3+
4+
export default test({
5+
async test({ assert, target, logs }) {
6+
const [b1] = target.querySelectorAll('button');
7+
flushSync(() => {
8+
b1.click();
9+
});
10+
flushSync(() => {
11+
b1.click();
12+
});
13+
assert.deepEqual(logs, [
14+
{ count: 0, doubled: 0 },
15+
{ count: 1, doubled: 2 },
16+
{ count: 2, doubled: 4 }
17+
]);
18+
}
19+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script>
2+
let count = $state(0);
3+
4+
function increment() {
5+
count += 1;
6+
}
7+
8+
$effect.pre(() => {
9+
const doubled = count * 2;
10+
$effect(() => {
11+
console.log({ count, doubled });
12+
});
13+
});
14+
</script>
15+
16+
<button onclick={increment}>
17+
clicks: {count}
18+
</button>

0 commit comments

Comments
 (0)