booleanstatesveltesveltekitsvelte-5

Why can the $state rune not handle a boolean condition ($effect needed)


I am a bit confused as to why the $state rune cannot handle a boolean condition. Why is that something that requires a separate rune, in this case $effect? In the Svelte documentation, they put an emphasize on using $effect as little as possible, but this seems like a pretty standard scenario to me so I am unsure as to why it does not work with $state.

Why does this work:

let isInteractivePage = $state(false);
$effect(() => {
    isInteractivePage = $page.url.pathname.startsWith('/interactive');
});

But this not:

let isInteractivePage = $state($page.url.pathname.startsWith('/interactive'));

Solution

  • The latter initializes a new state, which then is independent from the source. What you are looking for here is $derived which is a type of state that is updated based on dependencies.

    const isInteractivePage = $derived($page.url.pathname.startsWith('/interactive'));
    

    (It can be const to signal that the variable is not manually changed but internally it will update.)

    $effect, as the name implies, is for side-effects; things like interacting with DOM elements, using fetch to get new data, writing to localStorage, etc.

    If you use an $effect to write to state, based on state, it is easy to cause issues like infinite loops, so it is generally discouraged. Sometimes it may be necessary but this is a pretty clear case.