Skip to content

Commit ada3076

Browse files
authored
fix: account for proxified instance when updating bind:this (#18147)
Fixes #18145 I wonder why nulling happens after updating `bind:this` but not before, which would fix the issue as well, though not as efficiently. ### Before submitting the PR, please make sure you do the following - [x] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs - [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`. - [x] This message body should clearly illustrate what problems it solves. - [x] Ideally, include a test that fails without this PR but passes with it. - [x] If this PR changes code within `packages/svelte/src`, add a changeset (`npx changeset`). ### Tests and linting - [x] Run the tests with `pnpm test` and lint the project with `pnpm lint`
1 parent bd29b9e commit ada3076

5 files changed

Lines changed: 49 additions & 1 deletion

File tree

.changeset/full-waves-tease.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: account for proxified instance when updating `bind:this`

packages/svelte/src/internal/client/dom/elements/bindings/this.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export function bind_this(element_or_component = {}, update, get_value, get_part
4040
parts = get_parts?.() || [];
4141

4242
untrack(() => {
43-
if (element_or_component !== get_value(...parts)) {
43+
if (!is_bound_this(get_value(...parts), element_or_component)) {
4444
update(element_or_component, ...parts);
4545
// If this is an effect rerun (cause: each block context changes), then nullify the binding at
4646
// the previous position if it isn't already taken over by a different effect.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
const props = $props();
3+
// svelte-ignore state_referenced_locally
4+
export const name = props.name;
5+
</script>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { flushSync } from 'svelte';
2+
import { test } from '../../test';
3+
4+
export default test({
5+
async test({ assert, target, logs }) {
6+
const btn = target.querySelector('button');
7+
8+
flushSync(() => {
9+
btn?.click();
10+
});
11+
12+
flushSync(() => {
13+
btn?.click();
14+
});
15+
16+
assert.deepEqual(logs, [
17+
{},
18+
{ 0: { name: 'Row 0' } },
19+
{ 0: { name: 'Row 0' }, 1: { name: 'Row 1' } }
20+
]);
21+
}
22+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script>
2+
import Row from "./Component.svelte";
3+
4+
const nums = $state([]);
5+
const rows = $derived(nums.map(n => ({id: n, name: `Row ${n}` })));
6+
const refs = $state({});
7+
8+
$effect(() => {
9+
console.log({...refs});
10+
})
11+
</script>
12+
13+
<button onclick={() => nums.push(nums.length)}>Add</button>
14+
{#each rows as row (row.id)}
15+
<Row name={row.name} bind:this={refs[row.id]} />
16+
{/each}

0 commit comments

Comments
 (0)