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

React Router 6+结合Firebase实时数据库获取数据返回null求助

React Router 6+ 与 Firebase 实时数据库配合获取数据问题解决方案

核心问题分析

Firebase 的 onValue 是基于回调的异步 API,你的 getSingleEvent 函数在回调执行前就返回了初始的 null,导致 React Router 的 loader 拿到的是未完成异步操作的结果。

具体修复步骤

1. 将 getSingleEvent 改造为返回 Promise 的函数

把回调逻辑包裹在 Promise 中,当 Firebase 返回数据时 resolve 结果,发生错误时 reject:

import { ref, onValue } from "firebase/database";
import { db } from "./your-firebase-config"; // 替换为你的Firebase配置路径

function getSingleEvent(eventUUID) {
  return new Promise((resolve, reject) => {
    const eventRef = ref(db, `events/${eventUUID}`);
    onValue(eventRef, (snapshot) => {
      if (snapshot.exists()) {
        const eventData = snapshot.val();
        console.log(eventData); // 保留原有打印逻辑
        resolve(eventData); // 将数据传递给Promise调用者
      } else {
        resolve(null); // 无数据时返回null
      }
    }, (error) => {
      reject(error); // 捕获并传递错误
    });
  });
}

2. 在 React Router loader 中使用 async/await

修改 loader 为异步函数,等待 getSingleEvent 的 Promise 完成:

// main.js 路由配置
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import EventPage from "./EventPage";

const router = createBrowserRouter([
  {
    path: "/event/:eventUUID",
    element: <EventPage />,
    loader: async ({ params }) => {
      try {
        return await getSingleEvent(params.eventUUID);
      } catch (error) {
        console.error("获取事件数据失败:", error);
        return null; // 或抛出错误交由ErrorBoundary处理
      }
    },
  },
]);

3. 组件中正常使用 useLoaderData

现在 useLoaderData() 即可拿到正确的异步数据:

// EventPage.jsx
import { useLoaderData } from "react-router-dom";

function EventPage() {
  const eventData = useLoaderData();

  if (!eventData) {
    return <div>事件不存在或加载失败</div>;
  }

  return (
    <div>
      <h1>{eventData.title}</h1>
      <p>{eventData.description}</p>
    </div>
  );
}

关于 Suspense 和 Await 的补充说明

若要使用 Await 组件,需让 loader 返回包含 Promise 的对象,再配合 Suspense 包裹:

// loader 配置调整
loader: ({ params }) => {
  return {
    event: getSingleEvent(params.eventUUID)
  };
}
// EventPage 组件调整
import { Await, useLoaderData } from "react-router-dom";
import { Suspense } from "react";

function EventPage() {
  const data = useLoaderData();

  return (
    <Suspense fallback={<div>加载中...</div>}>
      <Await resolve={data.event}>
        {(eventData) => (
          <div>
            <h1>{eventData.title}</h1>
            <p>{eventData.description}</p>
          </div>
        )}
      </Await>
    </Suspense>
  );
}

注意:无论使用哪种方式,核心前提都是 getSingleEvent 必须返回正确的 Promise,否则 Await 也无法拿到有效数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:38:24