sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
18.41k stars 1.88k forks source link

(Svelte 5) `$effect` depending on `$page` runs twice #11460

Closed Fruup closed 1 week ago

Fruup commented 8 months ago

Describe the bug

This concerns the early access version of Svelte 5.

I have a page with a dynamic route parameter (/docs/[...path]/+page.svelte) that listens for the parameter (in $page.params.path) to change with an $effect. When initially loading the page, the effect is run twice instead of once.

This issue is not limited to dynamic route parameters.

Reproduction

Put this in a +page.svelte file somewhere:

<script lang="ts">
  import { page } from '$app/stores'

  // This is for some reason needed to prevent the effect below from running twice.
  // $effect(() => {
  //   $page
  // })

  $effect(() => {
    console.log('This should run once, but runs twice.', new Date().valueOf())

    // Do something with `$page`...
    $page
  })
</script>

Logs

This should run once, but runs twice. 1703424477666
This should run once, but runs twice. 1703424477667

System Info

System:
    OS: macOS 14.2.1
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 13.42 GB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.16.1 - ~/.nvm/versions/node/v18.16.1/bin/node
    npm: 9.5.1 - ~/.nvm/versions/node/v18.16.1/bin/npm
    pnpm: 8.9.0 - ~/Library/pnpm/pnpm
    bun: 1.0.19 - ~/.bun/bin/bun
  Browsers:
    Chrome: 120.0.6099.129
    Edge: 115.0.1901.188
    Safari: 17.2.1
  npmPackages:
    @sveltejs/adapter-auto: ^3.0.0 => 3.0.1 
    @sveltejs/kit: ^2.0.0 => 2.0.6 
    @sveltejs/vite-plugin-svelte: ^3.0.0 => 3.0.1 
    svelte: ^5.0.0-next.1 => 5.0.0-next.26 
    vite: ^5.0.3 => 5.0.10

Severity

annoyance

Additional Information

Weirdly, inserting another $effect depending on $page solves this issue:

$effect(() => {
  $page
})

Now the effect only runs once.

jhs512 commented 8 months ago

me too.

deeerwin commented 1 month ago

Does anyone know why this happens? My $effect runs twice also when console.log() an update on my state.

ndom91 commented 1 month ago

I'm running into this as well. I want to register a page view with my analytics library, so I have somethign like this:

onMount(() => {
  if (!dev) {
    analytics.init(env.PUBLIC_PROJECT_ID, { apiURL: env.PUBLIC_API_HOST })
  }
})

$effect(() => {
  const url = $page.url.pathname
  if ($page.url.searchParams.toString() !== "") {
    url += `?${$page.url.searchParams.toString()}`
  }

  if (!dev) {
    analytics.trackPageview(url)
  }
})

However, I end up getting 2x page views for each navigation. Looks like that trackpageView call in the $effect (which depends on $page) is called twice :thinking:

Using the following versions:

"@sveltejs/kit": "2.5.18",
"svelte": "5.0.0-next.175",
dummdidumm commented 1 week ago

I'm not able to reproduce this. Does this still occur in the latest version? If so, please provide a reproduction link (Stackblitz or github repo)

Fruup commented 1 week ago

@dummdidumm Seems to be fixed. Can't reproduce either (https://stackblitz.com/edit/sveltejs-kit-template-default-yd5fgs?file=src%2Froutes%2F%2Blayout.svelte).

dummdidumm commented 1 week ago

Closing as fixed then 👍