Skip to content

Commit 3dac3e7

Browse files
committed
fix
1 parent bed73ac commit 3dac3e7

File tree

4 files changed

+49
-11
lines changed

4 files changed

+49
-11
lines changed

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -604,28 +604,29 @@ function flush_queued_effects(effects) {
604604
if (eager_block_effects?.size > 0) {
605605
old_values.clear();
606606

607-
/** @type {Effect[]} */
608-
const filtered_effects = [];
609-
610-
outer: for (const e of eager_block_effects) {
607+
for (const e of eager_block_effects) {
611608
// Skip eager effects that have already been unmounted
612609
if ((e.f & (DESTROYED | INERT)) !== 0) continue;
613610

614-
// Skip effects that have related parent effects in the current flush,
615-
// as the inner ones will be run if its parent triggers it (eg. in a guard).
611+
// Run effects in order from ancestor to descendant, else we could run into nullpointers
612+
/** @type {Effect[]} */
613+
const ordered_effects = [];
616614
let ancestor = e.parent;
617615
while (ancestor !== null) {
618616
if (eager_block_effects.has(ancestor)) {
619-
continue outer;
617+
eager_block_effects.delete(ancestor);
618+
ordered_effects.unshift(ancestor);
620619
}
621620
ancestor = ancestor.parent;
622621
}
623622

624-
filtered_effects.push(e);
625-
}
623+
ordered_effects.push(e);
626624

627-
for (const e of filtered_effects) {
628-
update_effect(e);
625+
for (const e of ordered_effects) {
626+
// Skip eager effects that have already been unmounted
627+
if ((e.f & (DESTROYED | INERT)) !== 0) continue;
628+
update_effect(e);
629+
}
629630
}
630631

631632
eager_block_effects.clear();
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<script>
2+
let { p } = $props();
3+
$effect.pre(() => {
4+
console.log('running ' + p)
5+
})
6+
</script>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
mode: ['client'],
6+
async test({ assert, target, logs }) {
7+
const button = target.querySelector('button');
8+
9+
button?.click();
10+
flushSync();
11+
assert.deepEqual(logs, ['pre', 'running b', 'pre', 'pre']);
12+
}
13+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script>
2+
import Component from './Component.svelte';
3+
4+
let p = $state('b');
5+
6+
$effect.pre(() => {
7+
console.log('pre')
8+
if (p === 'a') p = null;
9+
})
10+
</script>
11+
12+
{#if p || !p}
13+
{#if p}
14+
<Component {p} />
15+
{/if}
16+
{/if}
17+
18+
<button onclick={() => p = 'a'}>a</button>

0 commit comments

Comments
 (0)