The term “resilient components” here is coming from Dan Abramov’s article Writing Resilient Components.
The principles he outlines are:
The principle we’re discussing in relation to Svelte is “Don’t stop the data flow.”, otherwise phrased as “Props and state can change, and components should handle those changes whenever they happen.”.
Let’s start by writing a Svelte component.
We want to write a component that fetches some photos from an API (this is taken from the
onMount example in the Svelte docs).
Now that we have a nice
PhotoGrid component, let’s write a component for selecting an album:
Beautiful, except that switching albums does not update the
This is not the automatic reactivity we were promised by Svelte.
Why does it not work?
The answer is that
onMount is not reactive, and so our component is not reactive.
onMount does not rerun when our props change, so it does not fetch new data when the album prop is changed.
If we were to write our
PhotoGrid component in React (with hooks) it would look something like this:
This component is written to be almost the same as our Svelte version, and yet it works when we change albums, the photos for the selected album are fetched!
The key difference is that we use
useEffect instead of
Using the dependency array we tell React that the effect (fetching photos) should rerun when the
album prop is changed.
Even if we didn’t think of this dependency ourselves
eslint-plugin-react-hooks would tell us about it.
When using React hooks there is no concept of
onMount because the idea of only running some code on mount leads to writing non-resilient components,
components that do one thing when they mount, and then don’t take prop changes into account.
Previously with React’s class component API we would need to use
componentDidUpdate, React hooks improves upon this, it encourages writing resilient components from the start, and we can also write cleanup logic in the same
To fix our Svelte version you might think we could use
but these lifecycle functions are related to the DOM being updated, not to prop updates.
We only want to rerun our fetching when the album prop is changed.
What is the best way to fix this then? I’m not sure what the best way is, but one way would be to implement
useEffect for Svelte ourselves:
With this code we use Svelte’s reactivity and a custom store to have our fetch rerun whenever the album prop is changed.
It works, I’m not sure this will work with SSR though, and the code is a bit verbose/convoluted.
IMO Svelte should make something like
useEffect part of the framework so that this could work better and be less verbose.
useEffectis not idiomatic Svelte.
onMountwhich results in non-resilient components.
useEffectwhich results in resilient components, assuming you listen to the linter.
I do like the direction Svelte is heading but I think this is one area that could be improved.
Software developer living in Toronto 🇨🇦 (and sometimes NYC 🗽).
Focused on Node | GraphQL | React | React Native.