在Svelte首次加载页面时进行额外的获取

huangapple go评论58阅读模式
英文:

An extra fetch during first page load in Svelte

问题

我正在使用Svelte、Flowbite-Svelte(UI)和TypeScript开发我的网站,目前一切顺利。

我有一个名为RandomBook.svelte的组件:

<script lang="ts">
  import { Card, Button, Badge, ButtonGroup, Tooltip } from "flowbite-svelte";
  import { page } from "$app/stores";
  import { BookManager } from "../lib/BookManager";

  let book = $page.data.randomBook;
  console.log(book.title);

  async function refresh() {
    const bm = new BookManager();
    let rb = await bm.getRandomBook();

    book = rb[0];
    console.log(book.title);
  }
</script>

<div>
  <Card img={book.img}>
    <Badge color="red" rounded>手气不错</Badge>
    <h5 class="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
      {book.title}
    </h5>
    <p class="mb-3 font-normal text-gray-700 dark:text-gray-400 leading-tight">
      【{book.region}】<a href="/book/author/{book.author}" class="hover:bg-sky-700">{book.author}</a>著{#if book.translated}&nbsp;| {book.copyrighter} 译{/if}<br />
      收录于:{book.purchdate},访问量:<Badge color="red">{book.vc.toLocaleString("en-US")}</Badge>
    </p>
    <ButtonGroup>
      <Button color="blue">详细信息&nbsp;<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-right-square-fill" viewBox="0 0 16 16">
        <path d="M0 14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2v12zm4.5-6.5h5.793L8.146 5.354a.5.5 0 1 1 .708-.708l3 3a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708-.708L10.293 8.5H4.5a.5.5 0 0 1 0-1z"></path>
      </svg></Button>
      <Button on:click={refresh}><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-clockwise" viewBox="0 0 16 16">
        <path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"></path>
        <path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z"></path>
      </svg></Button>
      <Tooltip placement="right">随机换一本</Tooltip>
    </ButtonGroup>
  </Card>
</div>

(https://github.com/taylorren/rsywx.svelte/blob/main/src/widget/RandomBook.svelte)

首次调用此组件是在根目录的+page.svelte+page.ts中:

<script lang="ts">
  import { Card, Button } from "flowbite-svelte";
  import BookToday from "../widget/BookToday.svelte";
  import LatestBook from "../widget/LatestBook.svelte";
  import RandomBook from "../widget/RandomBook.svelte";
  import Summary from "../widget/Summary.svelte";
  import Qotd from "../widget/Qotd.svelte";
  import ReadSummary from "../widget/ReadSummary.svelte";
  //export let data;
</script>
<title>任氏有无轩 | 藏书、读书、博客、维客、资源</title>
<div class="grow">
  <div class="flex flex-row flex-wrap m-8 gap-4 justify-center items-baseline">
    <LatestBook />
    <Summary />
    <RandomBook />
    <BookToday />
    <Qotd/>
    <ReadSummary/>
    ...
/** @type {import('./$types').PageLoad} */
import { ReadManager } from "../lib/ReadManager";
import { BookManager } from "../lib/BookManager";
import { MiscManager } from "../lib/MiscManager";

export async function load() {
  const bm: BookManager = new BookManager();
  const mm: MiscManager = new MiscManager();
  const rm: ReadManager = new ReadManager();

  const latestBook = await bm.getLatestBook(1);
  const randomBook = await bm.getRandomBook(1);
  const summary = await bm.getSummary();
  const booksToday = await bm.getBookToday();

  const readSummary = await rm.getSummary();

  const qotd = await mm.getQotd();

  return {
    latestBook: latestBook[0],
    randomBook: randomBook[0],
    summary: summary,
    booksToday: booksToday,
    readSummary: readSummary,
    qotd: qotd,
  };
}

网站加载良好,但存在一个小问题:

在第一次访问该页面或刷新时,随机书籍将显示一本书,然后迅速切换到另一本书。

我不知道为什么会发生这种情况。完整的代码位于https://github.com/taylorren/rsywx.svelte。

英文:

I am developing my site with Svelte, Flowbite-Svelte (UI) and TypeScript - and so far so good.

I have a component RandomBook.svelte:

&lt;script lang=&quot;ts&quot;&gt;
import { Card, Button, Badge, ButtonGroup, Tooltip } from &quot;flowbite-svelte&quot;;
import { page } from &quot;$app/stores&quot;;
import { BookManager } from &quot;../lib/BookManager&quot;;
let book = $page.data.randomBook;
console.log(book.title);
async function refresh() {
const bm = new BookManager();
let rb = await bm.getRandomBook();
book = rb[0];
console.log(book.title);
}
&lt;/script&gt;
&lt;div&gt;
&lt;Card img={book.img}&gt;
&lt;Badge color=&quot;red&quot; rounded&gt;手气不错&lt;/Badge&gt;
&lt;h5
class=&quot;mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white&quot;
&gt;
{book.title}
&lt;/h5&gt;
&lt;p class=&quot;mb-3 font-normal text-gray-700 dark:text-gray-400 leading-tight&quot;&gt;
【{book.region}】&lt;a
href=&quot;/book/author/{book.author}&quot;
class=&quot;hover:bg-sky-700&quot;&gt;{book.author}&lt;/a
&gt;
著{#if book.translated}&amp;nbsp;| {book.copyrighter} 译{/if}&lt;br /&gt;
收录于:{book.purchdate},访问量:&lt;Badge color=&quot;red&quot;
&gt;{book.vc.toLocaleString(&quot;en-US&quot;)}&lt;/Badge
&gt;
&lt;/p&gt;
&lt;ButtonGroup&gt;
&lt;Button color=&quot;blue&quot;&gt;详细信息&amp;nbsp;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; fill=&quot;currentColor&quot; class=&quot;bi bi-arrow-right-square-fill&quot; viewBox=&quot;0 0 16 16&quot;&gt;
&lt;path d=&quot;M0 14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2a2 2 0 0 0-2 2v12zm4.5-6.5h5.793L8.146 5.354a.5.5 0 1 1 .708-.708l3 3a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708-.708L10.293 8.5H4.5a.5.5 0 0 1 0-1z&quot;/&gt;
&lt;/svg&gt;&lt;/Button&gt;
&lt;Button on:click={refresh}&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;16&quot; fill=&quot;currentColor&quot; class=&quot;bi bi-arrow-clockwise&quot; viewBox=&quot;0 0 16 16&quot;&gt;
&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z&quot;/&gt;
&lt;path d=&quot;M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z&quot;/&gt;
&lt;/svg&gt;&lt;/Button&gt;
&lt;Tooltip placement=&quot;right&quot;&gt;随机换一本&lt;/Tooltip&gt;
&lt;/ButtonGroup&gt;
&lt;/Card&gt;
&lt;/div&gt;

(https://github.com/taylorren/rsywx.svelte/blob/main/src/widget/RandomBook.svelte)

The first call to invoke this component is in root's +page.svelte and +page.ts:

&lt;script lang=&quot;ts&quot;&gt;
import { Card, Button } from &quot;flowbite-svelte&quot;;
import BookToday from &quot;../widget/BookToday.svelte&quot;;
import LatestBook from &quot;../widget/LatestBook.svelte&quot;;
import RandomBook from &quot;../widget/RandomBook.svelte&quot;;
import Summary from &quot;../widget/Summary.svelte&quot;;
import Qotd from &quot;../widget/Qotd.svelte&quot;;
import ReadSummary from &quot;../widget/ReadSummary.svelte&quot;;
//export let data;
&lt;/script&gt;
&lt;title&gt;任氏有无轩 | 藏书、读书、博客、维客、资源&lt;/title&gt;
&lt;div class=&quot;grow&quot;&gt;
&lt;div class=&quot;flex flex-row flex-wrap m-8 gap-4 justify-center items-baseline&quot;&gt;
&lt;LatestBook /&gt;
&lt;Summary /&gt;
&lt;RandomBook /&gt;
&lt;BookToday /&gt;
&lt;Qotd/&gt;
&lt;ReadSummary/&gt;
...
/** @type {import(&#39;./$types&#39;).PageLoad} */
import { ReadManager } from &quot;../lib/ReadManager&quot;;
import { BookManager } from &quot;../lib/BookManager&quot;;
import { MiscManager } from &quot;../lib/MiscManager&quot;;
export async function load() {
const bm:BookManager= new BookManager();
const mm:MiscManager=new MiscManager();
const rm:ReadManager=new ReadManager();
const latestBook=await bm.getLatestBook(1);
const randomBook=await bm.getRandomBook(1);
const summary=await bm.getSummary();
const booksToday=await bm.getBookToday();
const readSummary=await rm.getSummary();
const qotd=await mm.getQotd();
return {
latestBook: latestBook[0],
randomBook: randomBook[0],
summary: summary,
booksToday: booksToday,
readSummary: readSummary,
qotd: qotd,
};
}

The site loads good but there is a small issue:

During my first visit to that page or a reload, the random book will show one book and then quickly switch to show another book.

I don't know how this could happen. The full code is located at https://github.com/taylorren/rsywx.svelte

答案1

得分: 1

The load function is executed both on the server and on the client.

在服务器和客户端都执行load函数。

The random book loaded by the server is shown first and is replaced by the client load.

服务器加载的随机书籍首先显示,然后由客户端加载替换。

To fix this: instead of using the "real" global fetch, use the fetch that is passed to the load function.

要解决这个问题:不要使用“真实”的全局fetch,而是使用传递给load函数的fetch。

export async function load({ fetch }) {
...
bm.getRandomBook(1, { fetch });
英文:

The load function is executed both on the server and on the client.

The random book loaded by the server is shown first and is replaced by the client load.

To fix this: instead of using the "real" global fetch, use the fetch that is passed to the load function.

export async function load({ fetch }) {
...
bm.getRandomBook(1, { fetch });
 private async _getBook(uri: string, opts?: { fetch: any }): Promise&lt;Book&gt; {
const ret = await (opts?.fetch ?? fetch)(uri);

By using this special fetch from SvelteKit the client re-uses the server responses from the server load.

https://kit.svelte.dev/docs/load#making-fetch-requests

huangapple
  • 本文由 发表于 2023年2月24日 06:42:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75551074.html
  • svelte

Svelte JS 和 :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定