fix: don't mark deriveds as clean if updating during teardown

pull/15997/head
Rich Harris 4 months ago
parent 8860ca6c1d
commit 210d127deb

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: don't mark deriveds as clean if updating during teardown

@ -9,7 +9,8 @@ import {
update_reaction, update_reaction,
increment_write_version, increment_write_version,
set_active_effect, set_active_effect,
push_reaction_value push_reaction_value,
is_destroying_effect
} from '../runtime.js'; } from '../runtime.js';
import { equals, safe_equals } from './equality.js'; import { equals, safe_equals } from './equality.js';
import * as e from '../errors.js'; import * as e from '../errors.js';
@ -172,13 +173,18 @@ export function execute_derived(derived) {
*/ */
export function update_derived(derived) { export function update_derived(derived) {
var value = execute_derived(derived); var value = execute_derived(derived);
var status =
(skip_reaction || (derived.f & UNOWNED) !== 0) && derived.deps !== null ? MAYBE_DIRTY : CLEAN;
set_signal_status(derived, status);
if (!derived.equals(value)) { if (!derived.equals(value)) {
derived.v = value; derived.v = value;
derived.wv = increment_write_version(); derived.wv = increment_write_version();
} }
// don't mark derived clean if we're reading it inside a
// cleanup function, or it will cache a stale value
if (is_destroying_effect) return;
var status =
(skip_reaction || (derived.f & UNOWNED) !== 0) && derived.deps !== null ? MAYBE_DIRTY : CLEAN;
set_signal_status(derived, status);
} }

@ -0,0 +1,22 @@
import { test } from '../../test';
import { flushSync } from 'svelte';
export default test({
html: `<button>toggle (false)</button>`,
async test({ assert, target, logs }) {
assert.deepEqual(logs, ['up', { foo: false, bar: false }]);
const button = target.querySelector('button');
flushSync(() => button?.click());
assert.deepEqual(logs, [
'up',
{ foo: false, bar: false },
'down',
{ foo: false, bar: false },
'up',
{ foo: true, bar: true }
]);
}
});

@ -0,0 +1,14 @@
<script>
let foo = $state(false)
let bar = $derived(foo)
$effect(() => {
console.log('up', { foo, bar });
return () =>{
console.log('down', { foo, bar });
};
});
</script>
<button onclick={() => foo = !foo}>toggle ({foo})</button>
Loading…
Cancel
Save