Skip to content

Commit 05636d3

Browse files
committed
WIP
1 parent 79e7203 commit 05636d3

File tree

4 files changed

+57
-3
lines changed

4 files changed

+57
-3
lines changed

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
import { get_descriptor, is_function } from '../../shared/utils.js';
1313
import { set, source, update } from './sources.js';
1414
import { derived, derived_safe_equal } from './deriveds.js';
15-
import { get, untrack } from '../runtime.js';
15+
import { get, is_destroying_effect, untrack } from '../runtime.js';
1616
import * as e from '../errors.js';
1717
import { LEGACY_PROPS, STATE_SYMBOL } from '#client/constants';
1818
import { proxy } from '../proxy.js';
@@ -366,7 +366,12 @@ export function prop(props, key, flags, fallback) {
366366

367367
// prop is written to, but there's no binding, which means we
368368
// create a derived that we can write to locally
369-
var d = ((flags & PROPS_IS_IMMUTABLE) !== 0 ? derived : derived_safe_equal)(getter);
369+
var overridden = false;
370+
371+
var d = ((flags & PROPS_IS_IMMUTABLE) !== 0 ? derived : derived_safe_equal)(() => {
372+
overridden = false;
373+
return getter();
374+
});
370375

371376
// Capture the initial value if it's bindable
372377
if (bindable) get(d);
@@ -376,6 +381,7 @@ export function prop(props, key, flags, fallback) {
376381
const new_value = mutation ? get(d) : runes && bindable ? proxy(value) : value;
377382

378383
set(d, new_value);
384+
overridden = true;
379385

380386
if (fallback_value !== undefined) {
381387
fallback_value = new_value;
@@ -384,7 +390,10 @@ export function prop(props, key, flags, fallback) {
384390
return value;
385391
}
386392

387-
if (has_destroyed_component_ctx(d)) {
393+
// special case — avoid recalculating the derived if
394+
// we're in a teardown function and the prop
395+
// was overridden locally
396+
if (is_destroying_effect && overridden) {
388397
return d.v;
389398
}
390399

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script>
2+
let { message, count } = $props();
3+
4+
$effect(() => () => {
5+
console.log(count, message);
6+
});
7+
</script>
8+
9+
<p>{count}</p>
10+
11+
<!-- we need these so that the props are made into deriveds -->
12+
<button disabled onclick={() => {
13+
count += 1;
14+
message += '!';
15+
}}>update</button>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { test } from '../../test';
2+
import { flushSync } from 'svelte';
3+
4+
export default test({
5+
async test({ assert, target, logs }) {
6+
const [increment, toggle] = target.querySelectorAll('button');
7+
8+
flushSync(() => toggle.click());
9+
assert.deepEqual(logs, [0, 'hello']);
10+
11+
flushSync(() => toggle.click());
12+
flushSync(() => increment.click());
13+
flushSync(() => increment.click());
14+
15+
assert.deepEqual(logs, [0, 'hello', 1, 'hello']);
16+
}
17+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script>
2+
import Component from "./Component.svelte";
3+
4+
let message = $state('hello');
5+
let count = $state(0);
6+
</script>
7+
8+
<button onclick={() => count++}>{count}</button>
9+
<button onclick={() => message = message === 'hello' ? 'goodbye' : 'hello'}>{message}</button>
10+
11+
{#if count < 2 && message === 'hello'}
12+
<Component {count} {message} />
13+
{/if}

0 commit comments

Comments
 (0)