mirror of https://github.com/sveltejs/svelte
fix: don't reset status of uninitialized deriveds (#18054)
If a new branch is created (e.g. if block becomes truthy) inside a fork and a derived is read inside the new branch for the first time, it will get reactions but its true value will stay uninitialized due to the fork. If the fork then commits, it will NOT change its value because it will not reexecute: there is no effect running after commit telling it to do that, because it was only read inside new effects which already ran while still inside the fork. Now, when that branch is removed (e.g. if block becomes falsy), the derived loses its reactions again and becomes disconnected, at which point the status is reset. So we end up with a maybe_dirty or clean derived and an uninitialized value, causing breakage if it's called again afterwards. The fix is to not reset the status in this case. Fixes https://github.com/sveltejs/kit/issues/15126 Fixes https://github.com/sveltejs/kit/issues/15318 Fixes https://github.com/sveltejs/kit/issues/15061pull/18073/head
parent
14adb8caa9
commit
adba758067
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: don't reset status of uninitialized deriveds
|
||||
@ -0,0 +1,20 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target }) {
|
||||
const [, toggle] = target.querySelectorAll('button');
|
||||
|
||||
toggle?.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, `<button>0</button> <button>toggle</button> 0`);
|
||||
|
||||
toggle?.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, `<button>0</button> <button>toggle</button>`);
|
||||
|
||||
toggle?.click();
|
||||
await tick();
|
||||
assert.htmlEqual(target.innerHTML, `<button>0</button> <button>toggle</button> 0`);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,13 @@
|
||||
<script>
|
||||
import { fork } from 'svelte';
|
||||
let show = $state(false);
|
||||
let count = $state(0);
|
||||
let d_count = $derived(count);
|
||||
</script>
|
||||
|
||||
<button onclick={() => count += 1}>{count}</button> <!-- just here so count is compiled as a source -->
|
||||
<button onclick={() => fork(() => show = !show).commit()}>toggle</button>
|
||||
|
||||
{#if show}
|
||||
{d_count}
|
||||
{/if}
|
||||
Loading…
Reference in new issue