3

In SvelteKit, I get "Subscribed" and "Unsubscribed" logged to the console each time I navigate between the /first and /second routes. I want to have the readable's start function run only once for each user who visits the website - allowing me to store fetched data that doesn't change often.

// stores.ts
import { readable } from 'svelte/store'
const { VITE_WEB_URL } = import.meta.env

export const message = readable('', set => {
  console.log('Subscribed')
  const fetchMessage = async () => {
    const url = `${VITE_WEB_URL}/api/message`
    const response: Response = await fetch(url)
    return await response.text()
  }
  fetchMessage()
    .then(set)
    .catch(err => console.error('Failed to get message', err))
  return () => {
    console.log('Unsubscribed')
  }
})
<!-- /routes/first.svelte -->
<script>
    import { message } from '../stores'
</script>

<h1>First: {$message}</h1>

<a href="/second">Second</a>
<!-- /routes/second.svelte -->
<script>
    import { message } from '../stores'
</script>

<h1>Second: {$message}</h1>

<a href="/first">First</a>

As I navigate between pages/routes in SvelteKit, unsubscribe is called so the next page/route invokes the start function as the "first" subscriber.

How can readable stores be shared across multiple pages/routes without re-running the start function? I've heard suggestions about using the template but have never seen an example.

Would the template get the store value and pass it as props to components or simply prevent the store from having a "last subscriber" (effectively keep the door open)?

4

2 回答 2

1

它说当第一个订阅者订阅时调用它,然后在最后一个订阅者取消订阅时调用删除函数。当您更改路由时,它会取消订阅所有订阅者,然后运行删除功能,然后当您到达下一条路由时,它会重新运行初始功能。

于 2021-06-19T03:32:06.330 回答
1

如果您使用的是模板,可读存储可以通过多种方式保持订阅状态,以免重新调用 start 函数:

  1. 在脚本或模板中直接在 __layout.svelte 中引用 $message
  2. 加载直接引用 $message 或包含这样做的 Svelte 组件的其他 Svelte 组件。
<!-- /lib/ComponentUsingMessage.svelte-->
<script>
  import { message } from '../stores'
</script>

<p>{$message}</p>
<!-- /routes/__layout.svelte-->
<script>
  import { message } from '../stores'
  // Or include a component in the template that loads $message...
  import ComponentUsingMessage from '$lib/ComponentUsingMessage.svelte'
</script>

<main>
  Both subscribe but do not unsubscribe while template is loaded:
  {$message}
  <ComponentUsingMessage/>

  <slot></slot>
</main>
于 2021-06-19T13:54:47.613 回答