React中useNavigate与useState实现列表项跳转详情页求助
解决React列表项跳转详情页的问题
步骤1:给数据源加唯一ID
先确保你的people数组里每个科学家对象都有唯一id,这是精准定位的基础:
// 示例people数组 const people = [ { id: 1, name: "阿尔伯特·爱因斯坦", profession: "理论物理学家", accomplishment: "提出相对论", dead: "true", nobel: "true" }, { id: 2, name: "斯蒂芬·霍金", profession: "宇宙学家", accomplishment: "黑洞辐射理论", dead: "true", nobel: "false" }, // 其他科学家数据... ];
步骤2:修正Scientist组件的跳转逻辑
你之前的navigate调用语法错误,第二个参数要放在navigate的括号里。这里改用动态路由传id(比用state传数据更可靠,刷新页面不会丢失):
import "./DummyItem.css"; import { useNavigate } from "react-router-dom"; export default function Scientist({ id, // 新增接收id属性 name, profession, accomplishment, dead, nobel, }) { const navigate = useNavigate(); return ( <div className="container"> <li className="dummy-item" onClick={() => { // 跳转带id的详情页路由 navigate(`/ItemSpecs/${id}`); }} style={{ cursor: "pointer" }} > <h5>{name}</h5> <p>profession: {profession}</p> <p>accomplishment: {accomplishment}</p> </li> </div> ); }
步骤3:完善PeopleList组件
给每个Scientist传递id,并且map的时候必须加key(用唯一id,这是React列表渲染的要求):
import Scientist from "./Scientist"; // 确保导入路径正确 export default function PeopleList() { // 你之前定义的navigate没用到,可以删掉 const ScientistsList = people .filter((scientist) => scientist.dead !== "true") .map((scientist) => ( <Scientist key={scientist.id} // 必须加key,用唯一id id={scientist.id} // 传递id给子组件 name={scientist.name} profession={scientist.profession} accomplishment={scientist.accomplishment} dead={scientist.dead} nobel={scientist.nobel} // 别忘了传递nobel属性 /> )); return ( <ul> {/* 注意li要放在ul里,符合HTML语义规范 */} {ScientistsList} </ul> ); }
步骤4:配置动态路由
在你的路由配置文件(比如App.js)里添加详情页的动态路由:
import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import PeopleList from "./PeopleList"; import ItemSpecs from "./ItemSpecs"; // 导入你的详情页组件 function App() { return ( <Router> <Routes> <Route path="/" element={<PeopleList />} /> {/* :id是动态参数占位符,匹配/ItemSpecs/1、/ItemSpecs/2这类路径 */} <Route path="/ItemSpecs/:id" element={<ItemSpecs />} /> </Routes> </Router> ); } export default App;
步骤5:编写详情页组件(ItemSpecs)
用useParams获取路由里的id,然后从people数组找到对应数据,用useState存储数据实现响应式展示:
import { useParams } from "react-router-dom"; import { useState, useEffect } from "react"; export default function ItemSpecs() { const { id } = useParams(); // 获取路由中的id参数 const [scientist, setScientist] = useState(null); useEffect(() => { // 把id转成数字,因为路由参数是字符串类型 const targetScientist = people.find(item => item.id === Number(id)); setScientist(targetScientist); }, [id]); // 当id变化时重新获取数据 if (!scientist) { return <div>加载中...</div>; } return ( <div className="specs-container"> <h2>{scientist.name}</h2> <p>职业: {scientist.profession}</p> <p>核心成就: {scientist.accomplishment}</p> <p>是否离世: {scientist.dead === "true" ? "是" : "否"}</p> <p>诺贝尔奖得主: {scientist.nobel === "true" ? "是" : "否"}</p> {/* 这里可以添加更多完整信息字段 */} </div> ); }
几个关键说明
- useNavigate的正确用法:第一个参数是跳转路径,第二个参数是可选配置(比如传临时数据用
state),但详情页用动态路由传id更稳妥,因为state数据刷新页面就会丢失。 - useParams的作用:专门用来获取动态路由里的参数,是列表页和详情页传递唯一标识的核心方式。
- useState的用法:在详情页里用来存储当前选中的科学家数据,配合
useEffect监听路由参数变化,实时更新展示内容。
内容的提问来源于stack exchange,提问作者0sirion
相关产品推荐
相关产品推荐

