React MERN应用无法传递ID至Fetch API,详情页加载失败
问题分析与解决方案
你的核心问题是职位ID未正确传递到详情页,导致请求无效URL引发JSON解析错误。以下是分步解决方法:
1. 修复React Router参数获取逻辑(最可能的原因)
如果你的项目使用的是React Router v6+,props.match.params已被废弃,需要改用useParams钩子来获取URL参数:
修改DetailsPage.js:
import styles from './DetailsPage.module.css'; import React, { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; // 导入useParams import jobsService from '../../utils/jobsService'; export default function DetailPage() { // 无需props参数 const [job, setJob] = useState({}); const [isLoading, setIsLoading] = useState(true); const { id } = useParams(); // 直接获取id useEffect(() => { const fetchData = async () => { if (!id) { // 先判断id是否存在,避免无效请求 setIsLoading(false); return; } try { // 注意:如果后端返回直接的job对象而非{ data: ... },这里不要解构data const jobData = await jobsService.show(id); setJob(jobData); } catch (error) { console.log(error); } finally { setIsLoading(false); } }; fetchData(); }, [id]); return ( <> {isLoading ? ( <div>Loading...</div> ) : ( <div className={styles.list}> <div className={styles.Grid}> <h3>{job.title}</h3> <p>{job.description}</p> </div> </div> )} </> ); }
2. 验证列表页的跳转链接
确保职位列表中跳转详情页的Link组件正确传递了ID:
// 示例列表项代码(假设你的列表组件) import { Link } from 'react-router-dom'; function JobItem({ job }) { return ( <div> <h4>{job.title}</h4> {/* 确认to属性中的id是job的有效ID */} <Link to={`/jobs/${job.id}`}>查看详情</Link> </div> ); }
检查job.id是否确实存在(比如后端返回的职位数据是否包含id字段)。
3. 完善API服务的错误处理
修改jobsService.js的show函数,添加ID校验和响应状态判断,避免无效请求和JSON解析错误:
async function show(id) { // 先校验ID是否存在 if (!id) { throw new Error('职位ID不能为空'); } console.log("show function called with id:", id); try { const res = await fetch(`http://localhost:3001/api/jobs/${id}`, { method: 'GET', headers: { 'Content-type': 'application/json', }, }); // 检查响应状态是否成功 if (!res.ok) { throw new Error(`请求失败:${res.status} ${res.statusText}`); } // 处理空响应的情况,避免JSON解析报错 const responseText = await res.text(); return responseText ? JSON.parse(responseText) : {}; } catch (error) { console.error('获取职位详情失败:', error); throw error; // 抛出错误让组件处理 } }
4. 确认后端响应格式
检查后端返回的单个职位数据格式:
- 如果后端直接返回职位对象(如
{ "id": 1, "title": "前端开发", "description": "..." }),组件中直接赋值setJob(jobData)即可; - 如果后端返回的是包裹在
data字段中的对象(如{ "data": { ... } }),则需要const { data } = await jobsService.show(id);。
内容的提问来源于stack exchange,提问作者kcam1996
相关产品推荐
相关产品推荐

