Skip to content
5 changes: 5 additions & 0 deletions .changeset/sour-jars-sniff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: mark reactions of `MAYBE_DIRTY` reactions too
4 changes: 2 additions & 2 deletions packages/svelte/src/internal/client/reactivity/sources.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export function internal_set(source, value) {
is_runes() &&
active_effect !== null &&
(active_effect.f & CLEAN) !== 0 &&
(active_effect.f & (BRANCH_EFFECT | ROOT_EFFECT)) === 0
(active_effect.f & (BRANCH_EFFECT | ROOT_EFFECT | BLOCK_EFFECT)) === 0
) {
if (untracked_writes === null) {
set_untracked_writes([source]);
Expand Down Expand Up @@ -280,7 +280,7 @@ function mark_reactions(signal, status) {
set_signal_status(reaction, status);

// If the signal a) was previously clean or b) is an unowned derived, then mark it
if ((flags & (CLEAN | UNOWNED)) !== 0) {
if ((flags & (CLEAN | UNOWNED | MAYBE_DIRTY)) !== 0) {
if ((flags & DERIVED) !== 0) {
mark_reactions(/** @type {Derived} */ (reaction), MAYBE_DIRTY);
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script>
let {config, value = $bindable()} = $props();

$effect.pre(() => {
config;
value = {}
});
</script>

a
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script>
let {config, value = $bindable()} = $props();

$effect.pre(() => {
config;
value = {}
});
</script>

b
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { flushSync } from 'svelte';
import { test } from '../../test';

export default test({
html: '<button></button> a',
async test({ assert, target }) {
const btn = target.querySelector('button');
flushSync(() => {
btn?.click();
});

assert.htmlEqual(target.innerHTML, `<button></button> b`);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script>
import A from "./A.svelte";
import B from "./B.svelte";

let schema = $state("any");
let value = $state({});

let config = $derived.by(() => {
value;
return schema;
});

let Thing = $derived.by(() => {
return config === "any" ? A : B;
});
</script>

<button onclick={()=>{
schema = "one";
}}></button>

<Thing {config} bind:value/>