Reputation: 6154
I have a store holding an object. I want to be able to have several reactive statements, each reacting to a change in a given property of the object.
Here's an example (REPL: https://svelte.dev/repl/38f15dc921034532be8dd2d774ca2096?version=3.48.0):
<script>
import { writable } from "svelte/store";
const catalogue = writable({ currentBook: "War'n'Peace", currentFood: "Authentic Napoli frozen pizza" });
$: $catalogue.currentBook, console.log("Current book has changed");
$: $catalogue.currentFood, console.log("Current food has changed");
function changeBook() { $catalogue.currentBook = "Putin's People"; }
function changeFood() { $catalogue.currentFood = "Authentic Valencia chorizo and mussels paella"; }
</script>
<button on:click={changeBook}>Change book</button>
<button on:click={changeFood}>Change food</button>
A click on "change food", for instance, triggers the two reactive statements, not just the one intended to react to a change on the food
property.
I'm not certain how stores and reactive statements play together, but it seems that reactivity happens even without a variable assignment. Unfortunately, it seems also that any change in the object triggers all the reactive statements referencing the store, which is not what I hoped.
Is there a solution you could suggest along those lines, or another approach?
Upvotes: 4
Views: 2320
Reputation: 184356
In your code the dependency is the store and without any additional code, that is the only thing that has change detection. You can add additional variables to separate out the properties and get more granular reactive statements:
$: ({ currentBook, currentFood } = $catalogue);
$: currentBook, console.log("Current book has changed");
$: currentFood, console.log("Current food has changed");
Here the log statement no longer have a direct dependency on the store, so they do not trigger for every store change.
You could also use derived stores:
const currentBook = derived(catalogue, c => c.currentBook);
const currentFood = derived(catalogue, c => c.currentFood);
$: $currentBook, console.log("Current book has changed");
$: $currentFood, console.log("Current food has changed");
Upvotes: 5