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

使用SolidStart从服务器加载数据异常问题求助

问题分析与解决

核心错误:未正确访问Resource的响应式状态

你代码里的关键问题是直接访问data.state而非调用data.state()。SolidStart中createServerData$返回的是Resource对象,其state是一个响应式访问器(函数),必须通过调用它才能获取当前状态,同时让createEffect追踪状态变化。

因为你没有调用data.state(),createEffect无法感知状态从pending变为ready的变化,所以首次加载时只打印初始的pending,后续状态更新不会触发effect重新执行。而导航返回时是客户端路由重新触发数据请求,组件重新挂载的行为偶然让你看到了预期输出,但这不是正确的处理方式。

其他优化点

  1. 复用PrismaClient实例:每次调用createServerData$都新建PrismaClient会导致数据库连接过多,应该全局复用实例。
  2. 移除不必要的信号:组件里的users信号完全多余,直接使用useRouteData返回的data()即可获取数据。

修正后的代码

import { createServerData$ } from "solid-start/server";
import { PrismaClient } from "@prisma/client";
import { For, createEffect } from "solid-js";
import { useRouteData } from "solid-start";

// 全局复用PrismaClient实例
const prisma = new PrismaClient();

export function routeData(){
    const users = createServerData$(async ()=>{
        const allusers = await prisma.user.findMany();
        console.log("all Users: ", allusers);
        // 全局实例无需每次断开连接,保持长连接更高效
        return allusers;
    });
    return users;
}

export default function Home(){
    const [dataLoad, setDataLoad] = createSignal(false);
    const data = useRouteData<typeof routeData>();
    
    createEffect(()=>{
        // 正确调用state访问器函数,触发响应式追踪
        const currentState = data.state();
        console.log("Loading Status:"+ currentState);
        if(currentState !== 'ready') return;
        
        const userData = data();
        if(userData === null){
            console.log("No Data");
        }else{
            console.log("data loaded");
            setDataLoad(true);
            console.log(JSON.stringify(userData)); // 用JSON.stringify打印对象,避免toString输出[object Object]
        }
    });
    
    return (
        <div>
            {dataLoad() ? (
                <For each={data()}>
                    {user => <div key={user.id}>{user.name}</div>}
                </For>
            ) : (
                <p>Loading...</p>
            )}
        </div>
    );
}

修正后生效的原因

  • 调用data.state()后,createEffect会正确追踪状态变化,无论首次SSR加载还是客户端路由导航,状态从pending到ready的变化都会触发effect重新执行。
  • 全局复用PrismaClient避免了频繁创建/断开数据库连接的性能问题。
  • 直接使用data()获取数据,减少了不必要的信号嵌套,代码更简洁。

内容的提问来源于stack exchange,提问作者MetaphysX

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 17:32:02