Skip to content
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

Bug: Svelte's snapshot store out of sync #4941

Open
phcoliveira opened this issue Jun 14, 2024 · 0 comments
Open

Bug: Svelte's snapshot store out of sync #4941

phcoliveira opened this issue Jun 14, 2024 · 0 comments
Labels

Comments

@phcoliveira
Copy link

XState version

XState version 5

Description

I am finishing to upgrade XState to v5 in a project using SvelteKit 4. However, I am finding some problems that I didn't have when using XState v4.

Previously, I had many occurrences like this, and they used to work fine.

<script>
import {useMachine} from '@xstate/svelte';
import {goto} from '$app/navigation';

import {fooMachine} from './foo.ts';

const {state} = useMachine(fooMachine);
</script>

{#if $state.matches('active')}
  <slot />
{:else}
  {#await goto('/somewhere/else')}
    Loading
  {/await}
{/if}

Now, with v5, the $snapshot store does not appear to work properly, or at least not fast enough because I get endless loops of redirection.

For fixing them, I had to do this.

<script>
import {useActor, useSelector} from '@xstate/svelte';
import {goto} from '$app/navigation';

import {fooMachine} from './foo.ts';

const {actorRef} = useActor(fooMachine);
const isActive = useSelector(actorRef, (snapshot) => {
  return snapshot.matches('active');
});
</script>

{#if $isActive}
  <slot />
{:else}
  {#await goto('/somewhere/else')}
    Loading
  {/await}
{/if}

Expected result

The $sessionSnapshot store, returned by useActor(), should match the state active.

Actual result

The $sessionSnapshot store remains in its initial state: inactive. However, a new subscription using useSelector() is updated.

Reproduction

https://codesandbox.io/p/github/phcoliveira/xstate-snapshot-problem/main?import=true

Additional context

The main files to checkout are:

src/lib/require-activated/require-activated.svelte
src/routes/activating/+page.svelte

But please do look around.

There are ways to circumvent this. For example, having the promise inside the logic of the machine and sending an event usually works too.

But I included in the first file a strange fix that uses useSelector instead of using the snapshot returned by useActor.

I can not really confirm that it used to work that way with XState 4 because, back then, I had these many actors (services, back then) inside one machine. When upgrading to XState 5, I dismembered them in order to make smaller machines and reduce the initial bundle size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant