solidjs router 默认会在路由切换时卸载组件,导致返回时重新渲染。本文介绍如何通过 createroot 手动管理组件生命周期,实现页面“缓存式”导航,避免重复挂载与状态丢失。
solidjs router 默认会在路由切换时卸载组件,导致返回时重新渲染。本文介绍如何通过 createroot 手动管理组件生命周期,实现页面“缓存式”导航,避免重复挂载与状态丢失。
在 SolidJS 中,
直接使用
核心方案是使用 createRoot 创建一个独立的、不受路由影响的响应式根节点:
import { createRoot, onMount } from 'solid-js';
import { Route, Router, Routes, hashIntegration } from '@solidjs/router';
const Home = () => {
onMount(() => console.log('Home mounted — only once'));
return <div>Home Page (state preserved!)</div>;
};
// ✅ 关键:用 createRoot 包裹组件,返回一个静态 Component
let disposeHome: () => void;
const cachedHome = createRoot((disposer) => {
disposeHome = disposer;
return <home></home>;
}) as unknown as Component;
// 可选:在页面卸载时清理(如 SPA 全局退出)
window.addEventListener('beforeunload', () => disposeHome());
const App = () => (
<router source="{hashIntegration()}"><nav><a href="#/home">Home</a>
<a href="#/user">User</a>
</nav><routes><route path="/home" component="{cachedHome}"></route><route path="/user" component="{()"><div>User Page</div>} />
</route></routes></router>
);
⚠️ 注意事项:
- createRoot 返回的组件不再响应路由参数变化(如 params, search)。若需动态数据,请配合 useLocation() 或 useParams() 在组件内部订阅,并确保副作用正确清理。
- 不要对 cachedHome 多次调用 createRoot —— 每个 createRoot 应仅初始化一次,复用其返回的组件引用。
- 若需支持多页缓存(如 Home + User 都需保留),需为每个页面单独创建并管理 createRoot 实例及对应的 dispose 函数。
- onMount / onCleanup 仍有效,但只在首次挂载和最终销毁时触发,不会因路由进出反复执行。
该方案本质是将组件从“路由驱动生命周期”迁移至“应用级持久化生命周期”,兼顾性能可控性与用户体验一致性。虽然 SolidJS 官方暂未内置











