如何在SolidJS的SSG模式下实现带不同参数的同页面跳转
解决SolidJS SSG模式下路由跳转后组件不更新的问题
核心原因
问题本质是组件没有正确追踪路由参数的响应式变化。SolidJS的useParams返回的是带有响应式访问器的对象,若组件初始化时仅读取一次参数值,后续参数变化不会触发组件重渲染。
具体解决方案
1. 正确使用useParams的响应式值
不要提前解构params对象并缓存值,而是在组件的JSX或响应式计算中直接访问params.id,确保SolidJS能追踪到参数变化:
import { useParams } from "@solidjs/router"; function User() { // 不要解构为 const { id } = useParams() const params = useParams(); // 直接访问 params.id,每次渲染都会触发依赖追踪 return <div>当前用户ID:{params.id}</div>; }
2. 让数据获取依赖路由参数
如果组件需要根据id获取数据,使用createResource并将参数作为数据源,确保参数变化时自动重新获取数据并更新组件:
import { createResource } from "solid-js"; import { useParams } from "@solidjs/router"; async function fetchUser(userId) { const res = await fetch(`/api/users/${userId}`); return res.json(); } function User() { const params = useParams(); // 将 () => params.id 作为数据源,参数变化时自动触发数据更新 const [userData] = createResource(() => params.id, fetchUser); return ( <div> {userData.loading && <div>加载中...</div>} {userData() && <div>用户名:{userData().name}</div>} </div> ); }
3. 应急方案:手动触发更新(不推荐)
SolidJS不建议手动强制重绘,但若确有特殊场景,可通过createSignal触发更新:
import { createSignal, createEffect } from "solid-js"; import { useParams } from "@solidjs/router"; function User() { const params = useParams(); const [, forceUpdate] = createSignal(0); // 监听参数变化,自动触发更新 createEffect(() => { params.id; // 建立参数依赖 forceUpdate(prev => prev + 1); }); return <div>当前用户ID:{params.id}</div>; }
4. 检查SSG动态路由预渲染配置
确保你的SSG配置中预渲染了所有需要的动态路由,避免静态文件缺失。例如在vite.config.js中:
import { defineConfig } from "vite"; import solid from "solid-start/vite"; import staticAdapter from "solid-start-static"; export default defineConfig({ plugins: [ solid({ adapter: staticAdapter({ // 预渲染所有用户路由 prerenderRoutes: async () => { // 替换为实际获取用户ID列表的逻辑 const userIds = ["123", "456", "789"]; return userIds.map(id => `/user/${id}`); }, }), }), ], });
内容的提问来源于stack exchange,提问作者David Apple
相关产品推荐
相关产品推荐

