React类组件通过Link路由传值报state未定义错误如何解决
问题现象
通过react-router-dom的Link组件state属性在两个React类组件间传递路由数据时,目标组件取数控制台抛出错误:Cannot read properties of undefined (reading 'state')
跳转端代码如下:
import React from "react"; import {Link} from 'react-router-dom'; class Header extends React.Component{ render(){ return( <div> <header className="mb-3"> <Link to={{ pathname:'/zone', state:'testing' }} className="btn icon icon-left btn-primary" > click me</Link> </header> </div> ) } } export default Header
接收端目标组件代码如下:
import React from "react"; class Zones extends React.Component{ componentDidMount() { console.log(this.props.location.state); } render(){ return( <div> <h1>Zones</h1> </div> ) } } export default Zones
问题根因
- 核心问题是目标组件
Zones没有接收到React Router注入的路由props,this.props.location本身为undefined,再访问state属性自然会抛出错误。默认情况下,只有被路由注册直接渲染的组件、且经过路由高阶组件包裹的类组件,才能拿到location/history/match这类路由属性。 - 代码缺少兜底逻辑:即使用户正常拿到了location对象,如果是直接输入地址访问目标路由、而非通过Link点击跳转,
location.state本身也会是undefined,直接访问同样存在报错风险。 - 注意:如果你用的是react-router-dom v6版本,官方已经默认移除了给类组件注入路由props的内置withRouter方法,直接按旧版写法写类组件是拿不到路由属性的
修复方案
- 给类组件注入路由props
- 如果你用的是react-router-dom v5及更早版本:直接从依赖包导入
withRouter高阶组件,包裹目标组件后导出即可,修改后的Zones组件代码如下:
import React from "react"; // 导入路由高阶组件 import { withRouter } from 'react-router-dom'; class Zones extends React.Component{ componentDidMount() { // 增加可选链做兜底判空 console.log(this.props.location?.state); } render(){ return( <div> <h1>Zones</h1> </div> ) } } // 包裹后导出 export default withRouter(Zones)- 如果你用的是react-router-dom v6版本:自行实现一个withRouter高阶组件,通过hooks拿到路由属性传给类组件。先在公共位置写好HOC:
后续和v5版本用法一致,导入自定义的withRouter包裹Zones组件导出即可。import { useLocation, useNavigate, useParams } from 'react-router-dom'; export const withRouter = (WrappedComponent) => { return (props) => { const location = useLocation(); const navigate = useNavigate(); const params = useParams(); return ( <WrappedComponent {...props} location={location} navigate={navigate} params={params} /> ) } } - 如果你用的是react-router-dom v5及更早版本:直接从依赖包导入
- 增加访问兜底
所有访问location.state的位置,统一用可选链?.或者提前判空,避免非Link跳转场景下的报错:const state = this.props.location?.state; // 后续逻辑判断state存在再做取值操作 - 检查路由配置
确认路由表中/zone路径对应的渲染组件确实为当前的Zones组件,不存在组件嵌套层级过深、props传递断层的问题。
内容的提问来源于stack exchange,提问作者Tashen Jazbi
相关产品推荐
相关产品推荐

