New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Svelte 5: store updates trigger component prop changes that didn't with 4 #11448
Comments
Scratch that i'm an idiot and svelte 4 actually has the same behavior in this case. |
Yes, any update to the store, even another property on an object, can end up triggering a prop change in a component when its values haven't really changed. IMO it's a breaking change because it can easily alter the behavior of existing components when running under 5 vs with 4, even when runes are not used. Although it's fairly easy to dedupe the changes within a component, those components might be 3rd party packages. Update: I think my comment overlapped your edit - we're saying the same thing. |
Svelte 5 has the same behavior in runes mode - i.e. the prop updates. So if that is an intended change it should be noted as breaking #11400 But for non-runes mode, it needs to behave as 4 did IMO. |
Is this something that causes real bugs in practise? I'm contemplating whether or not we should fix this, because it will likely mean loads of extra deriveds (one for each prop) in legacy mode for what I believe is a marginal fix in edge cases. |
It seems like a situation that would crucially rely on this effect should also have some kind of lifecycle or reactive check to work properly in most cases anyway. |
Yes, I found it from my first attempt upgrading some apps to 5. It isn't super-difficult to handle the change of behavior within the components but there is a real possibility that some components will break because of it and they might be external components. |
Not sure what you mean - something relying on the existing v4 behavior? IMO it's consistent in v4 - setting a component prop to the value it is already set to doesn't trigger a change whether that prop value comes from a reactive variable or a store. I think it would be confusing if components changed their behavior based on how the property value was passed in from being a reactive variable, store, or rune. |
Could you elaborate what exactly broke after upgrading, or put differently, how your real component looked like so that it broke? |
The specific component applied some CSS animations in a sequence when it saw a boolean toggle change (when it hadn't actually changed, but something else in the same store managing the state had). I haven't tested it with a string value yet but I expect it will affect a deep-zoom photo viewer that relies on the change to a base URL to trigger a reset of the view and cause it to start loading image tiles (where a store could update for other reasons, like registering a 'like'). I need to also test a lazy image component that shows a blur-hash image while the proper image loads as again, the URL changing is the trigger to start the process and the store that has it can be updated for other reasons (e.g. changing sizing / positioning) It's really anything where the prop-change is a trigger to something happening which is more than simply rendering values into the component template. I don't tend to use it, but could see people fetching data in response to data changing. Maybe it needs a "strict" vs "simple" configuration setting for legacy mode, where people could start with the strict mode when converting to reduce the number of issues, and switch to the altered behavior as a separate optional stepping stone to moving to native runes mode? |
I initially thought you were passing the store (and meant what you did with |
No, it's passing a property value from the store when some other update is made - the deduper was to prevent the update triggering a prop change where there wasn't really any change to the actual prop value itself. The complication is when the component may happen to be deeper within some 3rd party package you import and don't control or you just don't understand why your app is behaving strangely. The animation is playing enter / leave transitions via switching TailwindCSS classes, based on a toggle property and used in UI components which would suddenly start flickering and behaving weirdly as other properties were set in the stores containing the state. i.e. changing the selected item on a menu would trigger the menu to re-run the open animation when it shouldn't. I fixed it in the component but it could be a gotcha when anyone is upgrading from 4 to 5. I'm part way through dealing with some separate build issues, but think there are a few other places in my apps that could be impacted by this. Some may not be visible, but the updates could trigger things like Firestore subscriptions to re-fire, which is generally something to avoid ($) |
fixes #11448 by wrapping props in deriveds
fixes #11448 by wrapping props in deriveds
* fix: replicate Svelte 4 props update detection in legacy mode fixes #11448 by wrapping props in deriveds * fix test * Update packages/svelte/src/compiler/phases/3-transform/client/utils.js Co-authored-by: Rich Harris <[email protected]> * dedicated flag * prettier --------- Co-authored-by: Rich Harris <[email protected]>
Describe the bug
Setting a component prop to a store value causes the component prop to see a change with 5 when it didn't with 4.
i.e. it appeared to be deduped with 4 but isn't with 5
Reproduction
Svelte 4: https://svelte.dev/repl/d43370affcf9403b9a5566a9e9849da8?version=4.2.15
Toggle triggers a change in the component, Update doesn't (prop value stays the same).
Svelte 5: https://svelte-5-preview.vercel.app/#H4sIAAAAAAAAE41SQW6DMBD8ytaKFJAQ3BEgVflCeyo9ELJEVo3XwkuayvLfK-yIpEkPOa09npkd7dqJQSq0ovxwQncjilK8GiMywT9mudgTKkaRCUvz1C9IZftJGm5a3bIcDU0MDr4nyd1eIXgYJhphG3WFZZpwe0Pd0WhIo-YLLy9WJI-aha1b7klbhqCHevVPHJw6NWMJQ6csgk8je5h1z5I0MB2PCpMU3AK3HAzy2Rw6xuQMdQNXi5dzHk7g08WG_Z3XRfWU16NVVVwHpav9zEwaSJe9kv1X7WJQ37yFWhWR0PxHjR198x7qDbXVbhNDheYhf3WdcADrvxQoGpGJkQ5ykHgQJU8z-mzd_Sp-9gfgOaxV4aVdHOGmhGV_pDBXdEzCS3o3EhcDPab59L-vjIN4lQIAAA==
Update now triggers a change of the prop value, even though the value hasn't actually changed (see console log)
Logs
.
System Info
Severity
blocking an upgrade
The text was updated successfully, but these errors were encountered: