Search code examples
sveltesvelte-3

Trying to understand why changing a variable re-triggers reactive statements of unrelated variables


Context

Here's a simplified version of my context:

context I have a component which

  • fetches a collection of items from the server -> bookmarks [{title, url}, ...]
  • in a reactive statement, populates a new collection from bookmarks by adding a new property with the domain name of the url: `xbookmarks = [{title, url, domain}, ...]
  • makes it possible to filter bookmarks by domain, by displaying a list of checkboxes, one per domain:
    • this is achieved by declaring a filter: {domains: {domain:true|false, ...}} variable
    • the filter.domains map is populated in a reactive statement by iterating over xbookmarks and setting all domains to true
    • finally, a filterdBookmarks variable is computed in a reactive statement by filtering xbookmarks using filter
  • displays the filtered bookmarks

What I have tried

Here's the flow in pseudo-javascript:

let bookmarks=[]

let xbookmarks=[]
$: xbookmarks = bookmarks.map(b=>{...b, domain: computeDomain(b)})

let filter = {domains: {}}
$: filter.domains=extractDomains(xbookmarks)

let filterdBookmarks=[]
$: filterBookmarks = xbookmarks.filter(using filter)

Here's a link to the svelte REPL with the complete code described above: https://svelte.dev/repl/d07ffc88e4a34cb797d2ceb6ba0ec6a4?version=3.49.0

Problem

When I try to uncheck one of the domains checkboxes:

Expected behaviour:

filter changed => trigger recomputation of depending variables, i.e. filterdBookmarks

Actual behaviour:

filter changed => Svelte recomputes xbookmarks, then filter.domains which resets it back to all domains being checked, then filterdBookmarks

I can't understand why Svelte considers that xbookmarks depends on filter

When I looked into the JS code generated by Svelte, this shouldn't be happening:

dependency graph

As can be seen in the screenshot above, the generated code matches my intuition about the dependencies:

  1. xbookmarks is recomputed when bookmarks changes
  2. filter.domains is recomputed when xbookmarks changes
  3. filteredBookmarks is recomputed when either of filter of xbookmarks changes

P.S.: I have just started learning and playing with Svelte


Solution

  • This is probably a bug. The input_change_handler invalidates too many variables.

    This worked in v.3.2.0, see also this related question and issue opened for it.