svelte icon indicating copy to clipboard operation
svelte copied to clipboard

creating state inside derived expressions should be forbidden

Open Rich-Harris opened this issue 1 year ago • 2 comments

Describe the problem

Per https://github.com/sveltejs/svelte/pull/10240#issuecomment-1912206863 — if you have a case like this...

function createCounter() {
  let count = $state(0);
  return {
    get count() { return count },
    increment: () => count += 1
  }
}

let { count, increment } = $derived(createCounter());

...you're creating state inside the derived expression and then depending on that state. When the state changes, the derived expression is re-evaluated, recreating the original state.

Unsurprisingly, this does not do anything useful.

Describe the proposed solution

Creating state inside a derived expression should be an error.

Importance

nice to have

Rich-Harris avatar Jan 26 '24 15:01 Rich-Harris

This is complicated. This is only true of primitive state, but for deeply nested state, it's the only way some patterns can work unless you invoke effects to sync state (see my shopping cart REPL example).

trueadm avatar Jan 31 '24 00:01 trueadm

I'm not convinced that's true — my fork of that example works without creating state inside deriveds

Rich-Harris avatar Feb 01 '24 03:02 Rich-Harris

Simpler example — we decided that we want to prevent reads of state/deriveds created inside the derived, but creating them is okay (they might be class fields etc)

Rich-Harris avatar Mar 11 '24 14:03 Rich-Harris