You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte页面未水化+HMR不可恢复错误,跳转无渲染刷新才生效

Svelte + PocketBase页面跳转无内容、刷新恢复及HMR报错解决

问题现象

  • 页面跳转时无内容渲染,刷新页面后内容正常显示
  • 控制台出现报错:[HMR][Svelte] Unrecoverable HMR error in <+page>: next update will trigger a full reload

错误原因

  1. 异步数据未处理:page.ts的load函数返回的product是未resolve的Promise对象,页面直接访问product.name等属性时,Promise还处于pending状态,无法读取属性导致渲染失败
  2. 遍历目标错误:product是单个数据对象,却用{#each product as x}遍历,会遍历对象的键值对而非预期的图片数组,引发额外渲染异常,最终导致HMR崩溃

修复步骤

1. 正确处理异步数据

有两种方式确保数据resolve后再渲染:

方式一:页面中使用{#await}块(推荐)

修改page.svelte,等待Promise完成后再渲染内容:

<script lang="ts">
    export let data;
</script>

{#await data.product}
    <p>加载中...</p>
{:then product}
    <h1>{product.name}</h1>
    <p>{product.price}</p>
    <p>{product.desc}</p>
    <p>{product.expand?.user?.username}</p>
    <img
        class="avatar"
        src={`https://avatars.dicebear.com/api/identicon/${product.expand?.user?.username}.svg`}
        alt="avatar"
        width="40px"
    />
    <!-- 遍历expand中的image数组,对应你PocketBase的关联字段 -->
    {#each product.expand?.image || [] as x}
        <img
            class="avatar"
            src={x.url}
            alt="avatar"
            width="40px"
        />
    {/each}
{:catch error}
    <p>加载失败:{error.message}</p>
{/await}

方式二:在load函数中直接返回已resolve的数据

修改page.ts为异步函数,提前resolve Promise:

import { pb } from "$lib/pocketbase"

export const load = async ({ params }: any) => {
    const product = await pb.collection('products').getOne(params.productID, {
        expand: "user, image"
    })
    console.log(product)
    return {
        product
    }
}

此方式下,页面可保留原有结构,但仍需修正{#each}的遍历目标

2. 修正遍历目标

将遍历单个对象的{#each product as x}改为遍历关联的图片数组{#each product.expand?.image || [] as x},确保遍历的是数组类型数据

可选:添加类型定义(避免类型错误)

给page.ts添加类型约束,提升代码健壮性:

interface Params {
    productID: string;
}

interface Product {
    id: string;
    name: string;
    price: number;
    desc: string;
    expand: {
        user: { username: string };
        image: Array<{ url: string }>;
    };
}

export const load = async ({ params }: { params: Params }) => {
    const product = await pb.collection('products').getOne<Product>(params.productID, {
        expand: "user, image"
    })
    return {
        product
    }
}

内容的提问来源于stack exchange,提问作者snorre søvold

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 17:51:29