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

点击卡片跳转页展示详情 Firebase v8升v9模块化传id问题

问题核心原因

你的代码存在两类问题导致无法正常拉取数据:

  • 路由跳转链路没有正确传递文档id,详情页拿到的id值不合法,无法匹配到Firestore里的对应文档
  • Firebase v9模块化API调用逻辑错误,混淆了Promise对象和回调返回的文档快照,调用了不存在的方法导致数据读取失败
修复步骤

1. 列表页卡片跳转时正确携带id

点击卡片触发路由跳转时,必须把当前卡片对应的电影文档id拼入路由参数,以React Router v6为例:

import { useNavigate } from 'react-router-dom';

// 电影列表卡片组件
const MovieCard = ({ movie }) => {
  const navigate = useNavigate();
  const onCardClick = () => {
    // 跳转到详情页路由,路由需提前定义为 /movie/detail/:id 格式
    navigate(`/movie/detail/${movie.id}`);
  };

  return (
    <div onClick={onCardClick} className="movie-card">
      {/* 卡片原有展示内容 */}
    </div>
  );
};

2. 详情页从路由中提取正确的id

详情页加载时首先从路由参数中解析传递过来的文档id:

import { useParams } from 'react-router-dom';

const MovieDetailPage = () => {
  // 提取路由参数中的id,字段名需要和路由定义的参数名保持一致
  const { id } = useParams();
  const [detailData, setDetailData] = useState(null);
  const [loading, setLoading] = useState(false);

  // 后续数据请求逻辑
}

3. 修正Firebase v9的数据查询逻辑

原有代码错误地在Promise对象上调用快照方法,需要修正为操作回调返回的文档快照对象,同时增加id合法性校验:

useEffect(() => {
  // id不存在时终止请求,避免无效查询
  if (!id) {
    setLoading(false);
    return;
  }
  setLoading(true);

  // 构造文档引用
  const movieDocRef = doc(db, 'movie', id);
  getDoc(movieDocRef)
    .then((docSnapshot) => {
      // exists()、data() 都是回调返回的docSnapshot实例上的方法
      if (docSnapshot.exists()) {
        // 读取文档数据使用data()方法,同时把文档id合并入数据方便后续使用
        setDetailData({
          id: docSnapshot.id,
          ...docSnapshot.data()
        });
      } else {
        console.log('未找到对应电影文档');
      }
    })
    .catch(err => {
      console.error('拉取电影详情失败:', err);
    })
    .finally(() => {
      setLoading(false);
    });
}, [id]);
校验注意事项
  • 先在详情页组件顶层打印id值,确认拿到的id和Firestore控制台中movie集合下的目标文档id完全一致,无undefined、多余空格、拼写错误问题
  • 确认已经正确导入Firebase相关依赖:
    import { doc, getDoc } from "firebase/firestore";
    import { db } from '@/utils/firebase'; // 替换为你项目中db实例的实际导入路径
    
  • 页面渲染时增加加载态和空态判断,避免数据未返回时触发渲染报错:
    if (loading) return <div>内容加载中...</div>;
    if (!detailData) return <div>暂无对应电影信息</div>;
    
    return (
      <div className="movie-detail">
        {/* 详情字段正常渲染逻辑 */}
      </div>
    );
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:15:46