Svelte页面未水化+HMR不可恢复错误,跳转无渲染刷新才生效
Svelte + PocketBase页面跳转无内容、刷新恢复及HMR报错解决
问题现象
- 页面跳转时无内容渲染,刷新页面后内容正常显示
- 控制台出现报错:
[HMR][Svelte] Unrecoverable HMR error in <+page>: next update will trigger a full reload
错误原因
- 异步数据未处理:
page.ts的load函数返回的product是未resolve的Promise对象,页面直接访问product.name等属性时,Promise还处于pending状态,无法读取属性导致渲染失败 - 遍历目标错误:
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
相关产品推荐
相关产品推荐

