Reputation: 4665
What's the proper way to trigger reactivity in svelte when I am updating a property of an object inside of an array that's then passed as a Component's prop?
let items = [{
id: 1,
name: 'first'
}, {
id: 2,
name: 'second'
}];
function findItem(id) {
return items.find(item => item.id == id);
}
function modifyItem(id, changedProps) {
let item = findItem(id);
if(item) {
Object.assign(item, changedProps);
items = [...items]; // this does nothing
console.log(items); // correctly displays the modified items array
}
}
// ...
<MyList {items}/>
So I am passing down my modifyItem
function. A child component then calls it and wants to update the items
array. That works just fine, but the reactivity is not triggered (I assume because svelte doesn't recognize that an object in the array has been modified) so MyList
is never re-rendered.
What's the "proper"/"correct" way of doing this? It seems a bit inefficient to .map
the whole array just to create a new instance of the object and push it in. Any other way? Thanks a lot!
Upvotes: 6
Views: 3555
Reputation: 114757
It should work. Here's a working example. The counter which is a property of an item in the array is incremented as expected.
App.svelte:
<script>
import DisplayCounter from "./DisplayCounter.svelte";
let items = [{text: 'hello', count: 0}];
function incrementCounter() {
items[0].count++;
items = [...items];
}
</script>
<button on:click={incrementCounter}>Click me</button>
<DisplayCounter {items} />
DisplayCounter.svelte:
<script>
export let items = []
</script>
<div>{items[0].count}</div>
And here's the REPL: https://svelte.dev/repl/9c20112f09284ba983bf598012705c56?version=3.19.1
Upvotes: 1