React Router v6跳转详情页报param属性未定义TypeError错误
问题相关代码
HomePage首页组件
import React from 'react'; import axios from 'axios'; import { useState, useEffect } from 'react'; import { useNavigate,useParams } from 'react-router-dom'; import { Main } from '../components/Main'; import { Controls } from '../components/Controls'; import { ALL_COUNTRIES } from '../config'; import { List } from '../components/List'; import { Card } from '../components/Card'; import { Details } from './Details'; export const HomePage = () => { const [countries,setCountries] = useState([]); const navigate = useNavigate(); useEffect(() => { axios.get(ALL_COUNTRIES).then(({data})=>setCountries(data)) },[]); return ( <> <Controls/> <List> { countries.map((c)=> { const countryInfo={ img:c.flags.png, name:c.name, info: [ { title:'Population', description:c.population.toLocaleString(), }, { title:'Region', description:c.region, }, { title:'Flag', description:c.capital, }, ], }; return <Card key={c.name} onClick={(e)=>{navigate('/country/${c.name}')}} {...countryInfo}/> }) } </List> </> ); };
Details详情页组件
export const Details = ({match}) => { return ( <div> Details {match.param.name} <div/> ); };
报错现象
首页可正常渲染展示,点击国旗/卡片组件跳转二级详情页时,抛出错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'param')
项目使用react-router-dom V6版本。
错误原因
一共三处问题共同导致报错:
- 路由跳转的模板字符串语法错误:HomePage中调用navigate时,路径字符串用了单引号
'包裹,模板字符串插值语法${}必须用反引号`包裹才能生效,单引号包裹时${c.name}会被当成普通字符串,无法解析出真实的国家名称,跳转到的路径是错误的字面量地址。 - react-router-dom版本API不兼容:V6版本完全移除了V5及更早版本中自动注入给路由组件的
match/history/location属性,组件不会收到match这个prop,因此解构出的match值为undefined,读取undefined的属性自然会抛出类型错误。 - 参数属性名拼写错误:就算在V5版本下,路由参数存储在
match.params对象下,代码中写的match.param少了末尾的s,同样会出现找不到属性的问题。
修复方案
按以下步骤修改即可解决问题:
- 修正HomePage中的跳转路径写法,将单引号替换为反引号,让模板插值正常解析,建议对动态参数做URL编码编码避免特殊字符导致路由异常:
// 原错误写法:navigate('/country/${c.name}') // 修改为 navigate(`/country/${encodeURIComponent(c.name)}`) - 重写Details组件,使用V6官方提供的
useParamshook获取路由参数,不要依赖旧版的match prop,同时修正原组件中错误的div闭合标签:// 首先引入useParams import { useParams } from 'react-router-dom'; export const Details = () => { // 解构的属性名需要和路由配置中的动态参数名完全一致 // 例:路由path配置为"/country/:name",这里就解构name const { name } = useParams(); return ( <div> Details {name} </div> ); }; - 检查路由配置,确保详情页路由为V6标准写法,动态参数名和useParams中解构的名称一致,示例配置:
<Routes> {/* 其他路由 */} <Route path="/country/:name" element={<Details />} /> </Routes>
内容的提问来源于stack exchange,提问作者Michael Hamar
相关产品推荐
相关产品推荐

