Solid-Start读取URL参数异常:首次请求报错,刷新有时正常
问题解决:SolidJS中首次访问页面无法读取URL参数获取数据的问题
问题根源
- 资源加载时序问题:
createResource初始化时数据还未请求完成,此时birthday()返回undefined,直接访问.id会触发报错。 - 参数就绪时机:
useParams返回的响应式对象,在routeData初始化阶段可能还未填充id值,导致首次请求时用undefined调用Pocketbase接口,进而资源加载失败;刷新时参数已就绪,所以偶尔能正常渲染。
修复方案
1. 让资源请求依赖URL参数
修改routeData中的createResource,将params.id作为资源的依赖源,确保只有当id存在时才发起请求:
export function routeData() { const params = useParams(); // 以params.id为依赖,仅当id存在时执行请求 const [birthday, { mutate, refetch }] = createResource(() => params.id, async (id) => { if (!id) return null; try { const record = await pb.collection("birthdays").getOne(id, {}); console.log(record); return record; } catch (err) { toast.error('获取生日数据失败'); console.error(err); return null; } }); return { birthday, refetch }; }
2. 处理资源未就绪状态
在页面组件中,使用Show组件判断资源是否加载完成,避免直接访问undefined的属性:
export default function Page() { const { birthday, refetch } = useRouteData(); const [debugMode, setDebugMode] = createSignal(false); return ( <main> {/* 仅当birthday存在时渲染内容,否则显示加载提示 */} <Show when={birthday()} fallback={<div>加载中...</div>}> {(birthdayData) => <div>{birthdayData.id}</div>} </Show> <Toaster /> </main> ); }
可选:使用可选链简化写法
如果不需要加载提示,也可以用可选链操作符快速处理空值:
<div>{birthday()?.id}</div>
额外说明
- 依赖
params.id后,当URL参数变化时,createResource会自动重新发起请求,保证数据与路由同步。 - 加入
try/catch捕获请求错误,避免因接口调用失败导致页面崩溃,同时通过toast提示用户异常信息。
内容的提问来源于stack exchange,提问作者Scott Scharl
相关产品推荐
相关产品推荐

