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'));
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.