React-Router:用useNavigate/Link传值后组件无法展示数据
React Router跳转传值后详情页无法获取数据的解决方法
问题场景
开发求职看板项目时,从Firebase获取职位数据,点击职位卡片通过Link或useNavigate跳转至详情页,控制台能看到location中存在传递的数据,但在详情页组件中调用location.state内的属性始终返回undefined,无法渲染内容。
错误原因
- 跳转时传递的是整个jobs数组,而非当前点击的单个job对象,导致详情页无法直接获取目标职位数据;
- 详情页中对
location.state的访问路径错误,未匹配传递的数据结构; - 未处理
state为空的边界情况,可能引发报错。
修正步骤
1. 修改跳转时的传值逻辑
在Jobs.js中,将传递的jobs数组改为当前遍历的单个job对象:
// Jobs.js import { Link, useNavigate } from "react-router-dom"; import { useState } from "react"; // 补充缺失的useState导入 export default () => { const navigate = useNavigate(); const [jobs, setJobs] = useState([]); return ( <div> {jobs.map(job => { return ( <div key={job.id}> {/* 使用Link跳转,传递单个job对象 */} <Link to={`/view-contact-details/${job.id}`} state={{ job }} // 传递当前job,而非整个jobs数组 > <button>View</button> </Link> {/* 使用useNavigate跳转,传递单个job对象 */} <button onClick={() => { navigate(`/view-contact-details/${job.id}`, { state: { job } }); }} > Go To Job details </button> </div> ); })} </div> ); };
2. 修正详情页的数据访问逻辑
在ViewJobDetails.js中,通过正确路径访问state中的job数据,并添加可选链处理空值:
// ViewJobDetails.js import React from "react"; import { useLocation } from "react-router-dom"; export default () => { const location = useLocation(); const job = location.state?.job; // 用可选链避免state为空时报错 if (!job) { return <div>未找到职位信息</div>; // 处理无数据的情况 } return ( <> <div> <div> <div> <strong>Description:</strong> {job.description} </div> <div> <strong>Title:</strong> {job.title} </div> </div> </div> </> ); };
3. 修正路由组件名的笔误
App.js中导入的组件是ViewJobDetails,但路由中写的是ViewUserDetails,需统一:
// App.js import React from "react"; import Jobs from "./pages/jobs" import Form from "./pages/form" import { Routes, Route } from "react-router-dom" import ViewJobDetails from "./components/Job/ViewJobDetails"; // 导入组件名 export default () => { return ( <div className="App"> <Routes> <Route path='/' element={<Jobs/>} /> <Route path='/form' element={<Form/>} /> <Route path="/view-contact-details/:id" element={<ViewJobDetails/>} // 对应正确的组件名 /> </Routes> </div> ); };
补充说明
react-router-domv6中,Route无需exact属性,默认就是精确匹配;- 使用可选链
?.可以避免页面刷新后state丢失(刷新页面时state会清空)导致的报错; - 若需要通过URL参数
id重新从Firebase获取数据,也可以结合useParams实现,这样即使刷新页面也能正常加载数据:
// ViewJobDetails.js 可选方案:通过id重新请求数据 import { useParams, useEffect, useState } from "react-router-dom"; // 假设你有获取单个职位的函数 import { getJobById } from "../services/firebase"; export default () => { const { id } = useParams(); const [job, setJob] = useState(null); useEffect(() => { const fetchJob = async () => { const data = await getJobById(id); setJob(data); }; fetchJob(); }, [id]); if (!job) return <div>加载中...</div>; return ( // 渲染内容 ); };
内容的提问来源于stack exchange,提问作者Bryam Loaiza
相关产品推荐
相关产品推荐

