React Router跨页传参访问location.state报undefined错误排查
报错核心原因
ResultPage组件未使用withRouter包裹导出,类组件无法获取react-router注入的路由props,this.props.location本身为undefined,读取state属性直接触发类型错误。对比你的Product组件,是正确包裹了withRouter才可以调用this.props.history.push方法,结果页漏了这一步。- 代码未做任何空值兜底:即使正确包裹withRouter,若用户直接刷新结果页、从地址栏直接输入结果页路径访问,路由的
location.state默认值为undefined,链式访问深层属性依然会报错。 - 结果页里写的
console.log(this.state.data)本身逻辑错误:路由传递的参数存在props中,不在组件自身的state里,且你未给组件初始化state.data,这行单独运行也会抛错。
修复方案
1. 给ResultPage注入路由Props
在result.js顶部引入withRouter:
import { withRouter } from 'react-router-dom';
将文件末尾的导出语句从export default ResultPage;替换为:
export default withRouter(ResultPage);
修改后组件即可正常通过this.props获取location/history/match等路由对象。
2. 增加空值兜底逻辑,避免链式访问undefined
不要直接写长链式的属性访问,先判断数据是否存在,不存在时展示兜底提示或跳转回提交页,避免页面崩溃。参考修改后的render逻辑:
render() { // 逐层判断数据是否存在,不存在时默认赋值为null const routeState = this.props.location?.state; const resultContent = routeState?.data?.data; // 数据不存在时的兜底展示 if (!resultContent) { return <div className="Container">未获取到有效结果,请返回提交页重新操作</div> // 需要自动跳转的话可以打开下面这行 // this.props.history.replace('/product') } return ( <div className="Container"> <div className="result-section"> <div className="score">hAPPi SCORE: <br/> <span>{resultContent.score}</span></div> <div className="scale-container"> <Scale scale-id="scr-scale" style="score-scale" score={resultContent.score}/> </div> </div> <div className="analysis-section"> <div className="analysis-container"> <div className="analysis-title"> In-Depth Analysis </div> <div className="keywords-container"> <div className="section-titles"> Keywords </div> <div> <ul> {resultContent.keywords.map(kw => <h3 key={kw}>{kw}</h3> )} </ul> </div> </div> <div className="entity-container"> <div className="section-titles"> Entities </div> <div> <ul> {resultContent.entities.map(en => <h3 key={en}>{en}</h3> )} </ul> </div> </div> <div> <h1>Result</h1> <div> {resultContent.feedback} </div> </div> <hr></hr> </div> </div> </div> ); }
补充:列表渲染时必须给遍历的根元素加唯一key属性,否则控制台会抛出渲染警告,这里关键词、实体内容无重复的话可以直接用内容作为key值。
额外注意
路由state传参仅在通过路由跳转动作进入页面时生效,用户手动刷新页面、直接输入地址访问时state会自动清空,空值兜底是必须加的逻辑。如果需要刷新后依然保留结果,可以选择两种方案:
- 跳转时将结果数据同步存入
sessionStorage,结果页初始化时优先从storage读数据 - 后端返回结果时生成唯一结果id,跳转时把id拼在url路径/参数上,结果页初始化时根据id请求后端拿完整数据,适合数据量较大的场景。
内容的提问来源于stack exchange,提问作者Soccerball123
相关产品推荐
相关产品推荐

