fix: improve each block item equality for immutable mode (#10537)

* fix: improve each block item equality for immutable mode

* alter
pull/10544/head
Dominic Gannaway 2 years ago committed by GitHub
parent 01b6543739
commit 71db9edcdc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: improve each block item equality for immutable mode

@ -28,7 +28,7 @@ import {
DOMBooleanAttributes,
EACH_INDEX_REACTIVE,
EACH_IS_CONTROLLED,
EACH_IS_IMMUTABLE,
EACH_IS_STRICT_EQUALS,
EACH_ITEM_REACTIVE,
EACH_KEYED
} from '../../../../../constants.js';
@ -2259,8 +2259,8 @@ export const template_visitors = {
each_type |= EACH_IS_CONTROLLED;
}
if (context.state.analysis.immutable) {
each_type |= EACH_IS_IMMUTABLE;
if (context.state.analysis.runes) {
each_type |= EACH_IS_STRICT_EQUALS;
}
// Find the parent each blocks which contain the arrays to invalidate

@ -5,7 +5,7 @@ export const EACH_KEYED = 1 << 2;
/** See EachBlock interface metadata.is_controlled for an explanation what this is */
export const EACH_IS_CONTROLLED = 1 << 3;
export const EACH_IS_ANIMATED = 1 << 4;
export const EACH_IS_IMMUTABLE = 1 << 6;
export const EACH_IS_STRICT_EQUALS = 1 << 6;
export const PROPS_IS_IMMUTABLE = 1;
export const PROPS_IS_RUNES = 1 << 1;

@ -2,7 +2,7 @@ import {
EACH_INDEX_REACTIVE,
EACH_IS_ANIMATED,
EACH_IS_CONTROLLED,
EACH_IS_IMMUTABLE,
EACH_IS_STRICT_EQUALS,
EACH_ITEM_REACTIVE,
EACH_KEYED
} from '../../constants.js';
@ -852,9 +852,9 @@ function each_item_block(item, key, index, render_fn, flags) {
const item_value = each_item_not_reactive
? item
: (flags & EACH_IS_IMMUTABLE) === 0
? mutable_source(item)
: source(item);
: (flags & EACH_IS_STRICT_EQUALS) !== 0
? source(item)
: mutable_source(item);
const index_value = (flags & EACH_INDEX_REACTIVE) === 0 ? index : source(index);
const block = create_each_item_block(item_value, index_value, key);

@ -0,0 +1,16 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
immutable: true,
test({ assert, target }) {
const btn = target.querySelector('button');
flushSync(() => {
btn?.click();
});
assert.htmlEqual(target.innerHTML, `<button>Update</button><ul><li>test !!!</li></ul>`);
}
});

@ -0,0 +1,17 @@
<script>
let items = [{id:1,value: "test"}]
const update = () => {
const clone = items.slice();
clone[0].value += " !!!";
items = clone;
}
</script>
<button on:click={update} >Update</button>
<ul>
{#each items as item (item.id)}
<li>{item.value}</li>
{/each}
</ul>
Loading…
Cancel
Save