Skip to content

Commit

Permalink
fix: ensure correct parent effect is associated with render effects (#…
Browse files Browse the repository at this point in the history
…13274)

* fix: ensure correct parent effect is associated with render effects

* fix

---------

Co-authored-by: Rich Harris <[email protected]>
  • Loading branch information
trueadm and Rich-Harris authored Sep 17, 2024
1 parent eba64f7 commit b624380
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/khaki-camels-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: ensure correct parent effect is associated with render effects
5 changes: 4 additions & 1 deletion packages/svelte/src/internal/client/reactivity/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,10 @@ export function user_effect(fn) {

if (defer) {
var context = /** @type {ComponentContext} */ (component_context);
(context.e ??= []).push(fn);
(context.e ??= []).push({
fn,
parent: active_effect
});
} else {
var signal = effect(fn);
return signal;
Expand Down
15 changes: 11 additions & 4 deletions packages/svelte/src/internal/client/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -1050,11 +1050,18 @@ export function pop(component) {
if (component !== undefined) {
context_stack_item.x = component;
}
const effects = context_stack_item.e;
if (effects !== null) {
const component_effects = context_stack_item.e;
if (component_effects !== null) {
var previous_effect = active_effect;
context_stack_item.e = null;
for (var i = 0; i < effects.length; i++) {
effect(effects[i]);
try {
for (var i = 0; i < component_effects.length; i++) {
var component_effect = component_effects[i];
set_active_effect(component_effect.parent);
effect(component_effect.fn);
}
} finally {
set_active_effect(previous_effect);
}
}
component_context = context_stack_item.p;
Expand Down
2 changes: 1 addition & 1 deletion packages/svelte/src/internal/client/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type ComponentContext = {
/** context */
c: null | Map<unknown, unknown>;
/** deferred effects */
e: null | Array<() => void | (() => void)>;
e: null | Array<{ fn: () => void | (() => void); parent: null | Effect }>;
/** mounted */
m: boolean;
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { test } from '../../test';
import { flushSync } from 'svelte';

export default test({
async test({ assert, target, logs }) {
const [b1] = target.querySelectorAll('button');
flushSync(() => {
b1.click();
});
flushSync(() => {
b1.click();
});
assert.deepEqual(logs, [
{ count: 0, doubled: 0 },
{ count: 1, doubled: 2 },
{ count: 2, doubled: 4 }
]);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script>
let count = $state(0);
function increment() {
count += 1;
}
$effect.pre(() => {
const doubled = count * 2;
$effect(() => {
console.log({ count, doubled });
});
});
</script>

<button onclick={increment}>
clicks: {count}
</button>

0 comments on commit b624380

Please sign in to comment.