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

Next.js动态路由使用useSWR+Firebase获取实时数据偶现失败

问题根因分析
  • 初始状态未定义:你声明const [poolState, setPoolState] = useState()没有传初始值,首次渲染时poolState为undefined,此时如果直接读取poolState的属性或数组元素就会抛出未定义错误
  • 动态路由参数未就绪:Next.js Pages Router 的router.query在页面首次hydration完成前是未赋值的,此时sPoolPage为undefined,你的匹配逻辑无法命中对应池子数据
  • useEffect依赖缺失:你当前的useEffect仅监听了data变化,未监听sPoolPage,如果sPoolPage晚于接口数据返回才解析完成,不会重新触发匹配逻辑,导致poolState始终为空
  • 全量拉取数据再过滤效率低:无需拉取所有池子数据后再本地过滤,Google Realtime Database支持直接请求单个节点数据
修复方案

你可以直接优化为更精简的实现,去掉冗余的useState和useEffect,利用SWR的条件请求能力避免无效请求:

import PoolDetails from "../../components/PoolDetails";
import { Fragment } from "react";
import useSWR from "swr";
import { useRouter } from "next/router";

const fetcher = (...args) => fetch(...args).then((res) => res.json());

export default function SinglePoolPage(props) {
  const router = useRouter();
  const { sPoolPage } = router.query;

  // 条件请求:仅当sPoolPage存在时才发起请求
  const { data: poolData, error, isLoading } = useSWR(
    sPoolPage ? `https://samplefirebasebackendurl.app/pools/${sPoolPage}.json` : null,
    fetcher,
    {
      // 配置实时更新间隔,根据你的需求调整,单位毫秒
      refreshInterval: 1000,
      revalidateOnFocus: true // 窗口聚焦时自动重新拉取数据保证最新
    }
  );

  // 加载状态处理
  if (isLoading) return <div>数据加载中...</div>;
  // 错误状态处理
  if (error) return <div>数据加载失败,请刷新重试</div>;
  // 池子不存在处理
  if (!poolData) return <div>当前池子不存在</div>;

  return (
    <Fragment>
      <PoolDetails 
        id={sPoolPage}
        name={poolData.name}
        timer={poolData.timer}
      />
    </Fragment>
  );
}
改动说明
  • 移除了冗余的本地状态poolState和useEffect匹配逻辑,直接复用SWR返回的接口数据,减少多余渲染
  • 新增条件请求,确保动态路由参数就绪后才发起接口请求,避免无效请求和匹配失败
  • 直接请求对应池子的独立节点,减少数据传输量,提升加载速度
  • 新增了加载、错误、无数据三种边界状态处理,避免渲染时读取未定义数据
  • 新增SWR实时更新配置,满足数据频繁变动的实时展示需求,无需手动处理轮询逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 15:06:04