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

如何使用React + Firebase基于集合项ID创建动态路由?

解决React + Firebase动态路由与详情页面渲染问题

首先修正你代码里的小错误:Link的to属性里多了一个多余的闭合花括号,正确写法应该是:

<Link to={`/protocol/${item.id}`}>

接下来分三步实现动态路由和详情页渲染:

1. 配置动态路由

假设你用的是react-router-dom v6+,在路由配置文件(比如App.js或Routes.js)里添加动态路由规则:

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import ProtocolList from './ProtocolList'; // 你的列表组件
import ProtocolDetail from './ProtocolDetail'; // 要创建的详情组件

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<ProtocolList />} />
        {/* 动态路由,:id 是占位符,匹配任意值 */}
        <Route path="/protocol/:id" element={<ProtocolDetail />} />
      </Routes>
    </Router>
  );
}

export default App;

2. 创建详情组件并获取路由ID

创建ProtocolDetail.js组件,用useParams钩子提取路由里的ID,再从Firebase获取对应文档数据:

import { useState, useEffect } from 'react';
import { doc, getDoc } from 'firebase/firestore';
import { db } from './firebaseConfig'; // 你的Firebase配置文件
import { useParams } from 'react-router-dom';

function ProtocolDetail() {
  const { id } = useParams(); // 获取路由中的id参数
  const [protocol, setProtocol] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchProtocol = async () => {
      try {
        // 根据ID从Firebase集合获取文档
        const protocolDoc = await getDoc(doc(db, 'protocols', id));
        if (protocolDoc.exists()) {
          setProtocol({ id: protocolDoc.id, ...protocolDoc.data() });
        } else {
          console.log("找不到对应的协议文档");
        }
      } catch (error) {
        console.error("获取数据失败:", error);
      } finally {
        setLoading(false);
      }
    };

    if (id) {
      fetchProtocol();
    }
  }, [id]);

  if (loading) return <div>加载中...</div>;
  if (!protocol) return <div>未找到该协议</div>;

  return (
    <div className="container mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">{protocol.name}</h1>
      {/* 渲染其他字段,比如protocol.description等 */}
      <p>{protocol.description}</p>
    </div>
  );
}

export default ProtocolDetail;

3. 修正列表组件的Link写法

把你原来的列表组件里的Link错误修正后,完整代码示例:

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

function ProtocolList({ protocol }) {
  return (
    <div>
      {protocol.map((item) => {
        return (
          <div key={item.id} className="flex justify-start underline underline-offset-3">
            <Link to={`/protocol/${item.id}`}>
              <div className="mt-2 hover:text-pink-600 duration-300">{item.name}</div>
            </Link>
          </div>
        );
      })}
    </div>
  );
}

export default ProtocolList;

补充说明

  • 如果需要实时监听文档变化,可以把getDoc换成onSnapshot,这样数据更新时页面会自动刷新:
    useEffect(() => {
      const unsubscribe = onSnapshot(doc(db, 'protocols', id), (doc) => {
        if (doc.exists()) {
          setProtocol({ id: doc.id, ...doc.data() });
        }
        setLoading(false);
      });
    
      // 组件卸载时取消监听
      return () => unsubscribe();
    }, [id]);
    

内容的提问来源于stack exchange,提问作者Fear of the dark

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 14:12:43