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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 07:37:48