Changed $state randomly doesn't update the UI
Describe the bug
I have a piece of html below ("totalWin" is a piece of $state on the "bet"-object) and most of the time the value updates as expected:
<div class="flex flex-col justify-center items-center">
<div>
Test
</div>
<div
class={`text-xl font-normal`}
>
{currency.formatCurrency(bet.totalWin)}
</div>
</div>
But sometimes (randomly?) it doesn't reflect the new value of "totalWin" state (on iOS Safari). I debugged this and removed more and more code until I found what caused it. If I instead change to the code to below it works always (the only changed thing is that I removed the "Test" text from the sibling html node):
<div class="flex flex-col justify-center items-center">
<div>
</div>
<div
class={`text-xl font-normal`}
>
{currency.formatCurrency(bet.totalWin)}
</div>
</div>
How and why, you have any idea?
Reproduction
Sorry, this is a pretty big project.
Logs
System Info
System:
OS: macOS 15.4.1
CPU: (11) arm64 Apple M3 Pro
Memory: 316.48 MB / 18.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.12.0 - ~/.nvm/versions/node/v22.12.0/bin/node
npm: 10.9.0 - ~/.nvm/versions/node/v22.12.0/bin/npm
bun: 1.0.29 - ~/.bun/bin/bun
Browsers:
Chrome: 135.0.7049.115
Safari: 18.4
npmPackages:
svelte: ^5.0.0 => 5.28.2
Severity
blocking an upgrade
Is this reproduction enough to accurately mirror your use case: https://svelte.dev/playground/1f32901c94ab448683eda243ff664b9e?version=5.28.2? If so, I can't see any issue there, even on iOS Safari.
Thanks, but I guess it doesn't because your scenario works. I can also make it work my switching the two divs like this:
<div class="flex flex-col justify-center items-center">
<div
class={`text-xl font-normal`}
>
{currency.formatCurrency(bet.totalWin)}
</div>
<div>
Test
</div>
</div>
Feels like it has something to do with html hierarchy in some rare cases.
Don't know how to reproduce it in a simpler way. but pretty sure it's a bug in Svelte. I solved it by creating a component for just the "totalWin" which seems to work fine:
<script lang="ts">
import type { BetService } from "../service/bet-service.svelte";
import type { CurrencyService } from "../service/currency-service";
interface Props {
bet: BetService<unknown>;
currency: CurrencyService;
}
let { bet, currency }: Props = $props();
</script>
<span>{currency.formatCurrency(bet.totalWin)}</span>
Seems it could also be solved by just adding a key around it, maybe this could give you a clue about the bug?
{#key bet.totalWin}
{currency.formatCurrency(bet.totalWin)}
{/key}
Without a reproduction we have no clue sorry...can you try to slim down your project to provide one?