Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork4.6k
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
I keep running into the same issue with Svelte 5, and that's that my <script>const {emailAddress,sessionDuration }=$props();$effect(()=> {console.log('Sending an email to', emailAddress);// sendEmail(emailAddress, 'Email address updated successfully!'); });</script><h1>Hello!</h1><p>You've been active for {sessionDuration} seconds!</p> In the parent component, we do something like this: <script>import {onMount}from'svelte';importChildfrom'./Child.svelte';let sessionDuration=$state(0);let emailAddress=$state('');onMount(()=> {setInterval(()=> sessionDuration++,1000); });// I know this is contrived, but it's not unusual for me to end up with// a single large reactive "root state" from which different props are// picked and sent into child components.conststate=$derived({sessionDuration, emailAddress});</script><inputtype="email"bind:value={emailAddress} /><ChildemailAddress={state.emailAddress}sessionDuration={state.sessionDuration}/> This code has a bug where it sends an email every second, not just when the email address changes. This happensdespite Why? Because the parent component is rerendering <script>- const { emailAddress, sessionDuration } = $props();+ const props = $props();+ const emailAddress = $derived(props.emailAddress);+ const sessionDuration = $derived(props.sessionDuration); $effect(() => { console.log('Sending an email to', emailAddress); // sendEmail(emailAddress, 'Email address updated successfully!'); }); </script> <h1>Hello!</h1> <p>You've been active for {sessionDuration} seconds!</p> The To me, this feels very unintuitive, and it's annoying to have to write the extra boilerplate every time I want to create an I think it'd be much more intuitive if the same deduplication logic that happens at the boundaries of a What do you think? |
BetaWas this translation helpful?Give feedback.
All reactions
Replies: 1 comment 1 reply
-
This is a classic example of something that shouldn't have been an effect in the first place! Effects are about reacting to statebeing a certain way, not to statechanging in a certain way. If you want to react to changes, use a callback (which could be applied as an event listener or a function binding or whatever). If you apply this mindset when thinking about how data flows through your app, you will free yourself of anxiety around when effects re-run. Effects running more or less frequently is a question of optimisation, not semantics. If we always added deduplication at prop boundaries, it would benefit this one specific case at the cost of others. |
BetaWas this translation helpful?Give feedback.
All reactions
-
Thanks for your reply! So what you're saying is thatin general, effects should be allowed to run whenever? Taken to the extreme: If the Svelte team decided that all effects will, from now on, run on a 3 second timer in addition to in response to their dependencies changing, then thatshould not cause any problems. And any user code breaking from such a change would have been following thereact-to-changes anti-pattern. It sounds quite reasonable to me in theory. Let me try to incorporate that line of thinking into practice. :) My email example may have been badly chosen. Of course I just made it up on the spot to illustrate the problem. So I did a search through our code base to find out how we really use However, most of the first 20 usages seem like they could be easily refactored into In some cases though, the effects are used to trigger data loading, to start timers, or stuff like that. I'm not sure how these should be rewritten to avoid Finally, I didn't quite understand what you meant by "using a callback" as an alternative to using an effect. The way I see it, callbacks are a way for a child component to send eventsup the tree, while reactive props are a way to send change-eventsdown the tree. How would callbacks achieve the latter? |
BetaWas this translation helpful?Give feedback.