Most of it can be explained in a HN comment:
Component state just does its thing. You change it with = and the component is re-rendered.
Writable stores need to trigger changes with set() and you need to use $ whenever you reference it in a .svelte file so that Svelte handles subscription automatically.
Reactive statements $: are a bit more complex. Every variable inside those is referenced by the compiler so that it knows when you are mutating it. Either with = or if it's a writable store with set().
An aside, and I know complaints about hooks are very boring now, but I remember when React first arrived on the scene. The API was a delight. shouldComponentUpdate, willReceiveProps, etc. Everything was so clear from the first second you picked it up. Now? I’m less sure.
I prefer the functional programming approach of React, but I love the performance and some of the developer ergonomics of Svelte.
In Svelte you never think about these or other considerations (eg: useMemo). Just update some state and that's it. Svelte will render consistently faster than React, with less code to write (and maintain).
It's true with React you get a bit more flexibility but I have yet to find a situation that cannot be solved with Svelte.