fix: allow NaN in key blocks (#17642)

* fix: allow NaN in key blocks

* lol whoops

* Update packages/svelte/src/internal/client/dom/blocks/key.js

Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>

---------

Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
pull/17615/head
Rich Harris 5 months ago committed by GitHub
parent bd7b8aa108
commit 57cb393796
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: allow `{#key NaN}`

@ -4,6 +4,8 @@ import { block } from '../../reactivity/effects.js';
import { hydrate_next, hydrating } from '../hydration.js';
import { BranchManager } from './branches.js';
const NAN = Symbol('NaN');
/**
* @template V
* @param {TemplateNode} node
@ -23,6 +25,11 @@ export function key(node, get_key, render_fn) {
block(() => {
var key = get_key();
// NaN !== NaN, hence we do this workaround to not trigger remounts unnecessarily
if (key !== key) {
key = /** @type {any} */ (NAN);
}
// key blocks in Svelte <5 had stupid semantics
if (legacy && key !== null && typeof key === 'object') {
key = /** @type {V} */ ({});

@ -0,0 +1,17 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
html: '<button>update</button><p>it rendered</p>',
test({ assert, target, logs }) {
assert.deepEqual(logs, ['rendering']);
const btn = target.querySelector('button');
flushSync(() => btn?.click());
// should not re-render
assert.deepEqual(logs, ['rendering']);
assert.htmlEqual(target.innerHTML, '<button>update</button><p>it rendered</p>');
}
});

@ -0,0 +1,10 @@
<script>
let x = $state(NaN);
</script>
<button onclick={() => x = NaN}>update</button>
{#key x}
{console.log('rendering')}
<p>it rendered</p>
{/key}
Loading…
Cancel
Save