Skip to content

Commit e3cff9b

Browse files
committed
add test
1 parent de30bec commit e3cff9b

File tree

4 files changed

+60
-5
lines changed

4 files changed

+60
-5
lines changed

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @import { Derived, Source } from './types.js' */
1+
/** @import { Source } from './types.js' */
22
import { DEV } from 'esm-env';
33
import {
44
PROPS_IS_BINDABLE,
@@ -22,6 +22,7 @@ import { safe_equals } from './equality.js';
2222
import * as e from '../errors.js';
2323
import { BRANCH_EFFECT, DESTROYED, LEGACY_DERIVED_PROP, ROOT_EFFECT } from '../constants.js';
2424
import { proxy } from '../proxy.js';
25+
import { teardown } from './effects.js';
2526

2627
/**
2728
* @param {((value?: number) => number)} fn
@@ -292,8 +293,6 @@ export function prop(props, key, flags, fallback) {
292293

293294
/** @type {() => V} */
294295
var getter;
295-
/** @type {Derived} */
296-
var derived_getter;
297296
if (runes) {
298297
getter = () => {
299298
var value = /** @type {V} */ (props[key]);
@@ -305,7 +304,7 @@ export function prop(props, key, flags, fallback) {
305304
} else {
306305
// Svelte 4 did not trigger updates when a primitive value was updated to the same value.
307306
// Replicate that behavior through using a derived
308-
derived_getter = with_parent_branch(() =>
307+
var derived_getter = with_parent_branch(() =>
309308
(immutable ? derived : derived_safe_equal)(() => /** @type {V} */ (props[key]))
310309
);
311310
derived_getter.f |= LEGACY_DERIVED_PROP;
@@ -350,12 +349,22 @@ export function prop(props, key, flags, fallback) {
350349
// The derived returns the current value. The underlying mutable
351350
// source is written to from various places to persist this value.
352351
var inner_current_value = mutable_source(prop_value);
352+
353+
teardown(() => {
354+
// If the getter from the parent returns undefined, switch
355+
// to using the local value from inner_current_value instead,
356+
// as the parent value might have been torn down
357+
if (getter() === undefined) {
358+
from_child = true;
359+
}
360+
});
361+
353362
var current_value = with_parent_branch(() =>
354363
derived(() => {
355364
var parent_value = getter();
356365
var child_value = get(inner_current_value);
357366

358-
if (from_child || (derived_getter !== undefined && (derived_getter.f & DESTROYED) !== 0)) {
367+
if (from_child) {
359368
from_child = false;
360369
was_from_child = true;
361370
return child_value;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script>
2+
let { x } = $props();
3+
4+
$effect(() => {
5+
console.log('init')
6+
7+
x = () => {
8+
console.log('teardown')
9+
}
10+
11+
return () => {
12+
x();
13+
}
14+
})
15+
</script>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ assert, logs, target }) {
6+
const [btn1] = target.querySelectorAll('button');
7+
8+
btn1?.click();
9+
flushSync();
10+
11+
btn1?.click();
12+
flushSync();
13+
14+
btn1?.click();
15+
flushSync();
16+
17+
assert.deepEqual(logs, ['init', 'teardown', 'init', 'teardown']);
18+
}
19+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script>
2+
import Component from "./Component.svelte";
3+
4+
let toggle = $state(true);
5+
</script>
6+
7+
<button onclick={() => toggle = !toggle}>toggle</button>
8+
9+
{#if toggle}
10+
<Component />
11+
{/if}
12+

0 commit comments

Comments
 (0)