-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Common auto-save pattern does not work for inputs #14911
Comments
This behavior is expected, the blur event simply takes longer to reference the object than the click event takes to turning it null If you use onmousedown instead of onclick you don't even need to simulate waiting It's not a bug, it's the correct behavior To fix it, just grab the reference before waiting |
I'm not sure if this is the case. The blur is supposed to fire before the click, because there is no Screen.Recording.2025-01-06.at.15.27.21.movThis can also be triggered by other things than click, for example client side navigation. If you perform a client side navigation, and the prop is derived by some data + route params, then the source may change, causing similar |
It fires before, but because of the await the console.log line only runs after React behaves differently because the value of a state only updates on the next render That's why: const [count, setCount] = useState(0)
console.log(count) // logs 0
setCount(1)
console.log(count) // logs 0 you can reference the previous value not because it is the correct behavior, but because of a stale closure |
I see! But shouldn't Svelte keep the closure so this doesn't happen? |
Not really I understand where your expectation comes from, coming from react But I don't think that's most people's expectation, that's not how javascript works |
This makes sense, but i think it was a little bit difficult to wrap our heads around this behaviour since it worked fine in Svelte 4: https://svelte.dev/playground/2b6ba5779ffe4ae2ac2e5f493d1d14e0?version=4.0.5 I've always felt that Svelte gives you superpowers when combining state and the DOM, and this is a case where it feels like Svelte 5 does not fill this gap. |
This is somewhat related to #14707 TBH with code like: {#if data}
<Input item={data.item} />
{/if} I would assume that the But at the same time, Svelte cannot know (?) that you are holding a reference to |
Maybe Svelte needs a
error similar to React when you're updating state in an unmounted component? This would make this a lot clearer. |
Svelte 4, like React, had a render cycle (although infinitely more efficient), but in the end it was also a matter of synchronization
And it really can't in synchronous code, but race conditions are something you have to learn to deal with in asynchronous javascript code.
I can see this working |
I've also felt numerous time that this goes against how Also, do not get too hung up in the simple reproduction i've provided - i tried creating a minimal repro to showcase the issue. I've met a lot tougher cases in our enterprise app where we are surprised by why it doesn't work, and it's always a tiny piece of code that in some unexpected way references a value that has become undefined. It's really really difficult to trace these code-paths, because they aren't visible in any way. It would be really nice if Svelte gave a helping hand in these cases, or if there was a way to make TypeScript actually know that it can be undefined automatically. This becomes a case where you "just have to know" that this won't work. Code that behaves like this is prone to creating bugs (cough Vanilla JS cough). |
Describe the bug
Using
onblur
for autosaving inputs is a common pattern, and it seems that if the save-callback takes more than 100ms then Svelte does not behave as expected.Related issue: sveltejs/kit#13276
This bug is possible to work around, but it really messes with our mental model of how props/state work. Also note that while setting up the repo it behaved flaky. Sometimes i was not able to trigger the bug at all, while other times it would work with just
Promise.resolve()
(using no timeout at all to mimic a request). Not sure if this is because of HMR 🤷Reproduction
Minimal repro: https://svelte.dev/playground/2b6ba5779ffe4ae2ac2e5f493d1d14e0?version=5.16.2
Screen.Recording.2025-01-06.at.13.09.48.mov
Logs
No response
System Info
Severity
annoyance
The text was updated successfully, but these errors were encountered: