fix: ensure reactions are correctly attached for unowned deriveds (#15158)

* fix: ensure reactions are correctly attached for unowned deriveds

* tune
pull/15156/head
Dominic Gannaway 7 months ago committed by GitHub
parent 970aa7cfaa
commit 7bef5963bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: ensure reactions are correctly attached for unowned deriveds

@ -802,12 +802,19 @@ function process_effects(effect, collected_effects) {
if (is_branch) {
current_effect.f ^= CLEAN;
} else {
// Ensure we set the effect to be the active reaction
// to ensure that unowned deriveds are correctly tracked
// because we're flushing the current effect
var previous_active_reaction = active_reaction;
try {
active_reaction = current_effect;
if (check_dirtiness(current_effect)) {
update_effect(current_effect);
}
} catch (error) {
handle_error(error, current_effect, null, current_effect.ctx);
} finally {
active_reaction = previous_active_reaction;
}
}
@ -952,13 +959,11 @@ export function get(signal) {
var derived = /** @type {Derived} */ (signal);
var parent = derived.parent;
if (parent !== null) {
if (parent !== null && (parent.f & UNOWNED) === 0) {
// If the derived is owned by another derived then mark it as unowned
// as the derived value might have been referenced in a different context
// since and thus its parent might not be its true owner anymore
if ((parent.f & UNOWNED) === 0) {
derived.f ^= UNOWNED;
}
derived.f ^= UNOWNED;
}
}

@ -0,0 +1,5 @@
<script>
let { value = $bindable() } = $props()
</script>
<button onclick={() => value = 'a'}>change</button>

@ -0,0 +1,5 @@
<script>
let {disabled = false} = $props()
</script>
{disabled}

@ -0,0 +1,16 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, target }) {
let [btn1, btn2] = target.querySelectorAll('button');
btn1?.click();
flushSync();
btn2?.click();
flushSync();
assert.htmlEqual(target.innerHTML, `<button>change</button><button>change</button>\nfalse`);
}
});

@ -0,0 +1,11 @@
<script>
import Child2 from './Child2.svelte'
import Child from './Child.svelte'
let loginname = $state('')
let password = $state('')
</script>
<Child bind:value={loginname} />
<Child bind:value={password} />
<Child2 disabled={!loginname || !password} />
Loading…
Cancel
Save