React Router Link传参返回时statusUser未定义错误的解决请求
location.state未定义的TypeError问题 我来帮你分析这个问题并给出实用的解决方案~
问题根源
你遇到的TypeError: Cannot read property 'statusUser' of undefined错误,本质是从UserDetail页面返回User页面时,this.props.location.state不存在了:
- 从Sidebar跳转到User时,你在Link的
state里传递了statusUser: 'abc',所以User组件能正常读取location.state.statusUser; - 但从UserDetail点击Back按钮时,你的Link只写了
pathname: '/user',没有传递state参数,这时候User组件的this.props.location.state就变成了undefined,直接访问statusUser自然会报错。
另外注意你的代码里有一些拼写小错误:比如Sidebar里的Commponent应该是Component,User组件的类名user应该大写为User,这些细节也可能导致潜在问题哦~
方案1:在User组件中添加空值检查(最推荐,通用场景)
在读取location.state之前先判断它是否存在,从根源避免访问undefined属性的错误,这是React开发中处理可选props的常规操作:
方式A:使用可选链+空值合并操作符(ES2020+,简洁)
修改User.jsx的render方法:
class User extends Component { render() { // 用可选链?.判断state是否存在,空值合并??设置默认值 const statusUser = this.props.location.state?.statusUser ?? 'default_status'; return ( <UserTable status={statusUser}/> ) } }
方式B:使用短路逻辑判断(兼容旧环境)
如果你的项目不支持ES2020语法,就用&&做前置判断:
class User extends Component { render() { const statusUser = this.props.location.state && this.props.location.state.statusUser || 'default_status'; return ( <UserTable status={statusUser}/> ) } }
方案2:在UserDetail的Back Link中传递state
如果你希望返回User页面时,依然保持和从Sidebar跳转过来一致的state,可以在UserDetail的Back Link里带上当前页面的state:
修改UserDetail.jsx的Back按钮Link:
class UserDetail extends Component { render(){ return( <> <p>{this.props.location.state.statusUser}</p> {/* 把当前页面的state传递回User页面 */} <Link to={ { pathname: `/user`, state: { statusUser: this.props.location.state.statusUser } } }><Button>Back</Button></Link> </> ) } }
这样返回时User组件的location.state就依然存在,不会报错。
方案3:将state存入组件自身的state(持久化状态场景)
如果你想让User组件的状态不受路由跳转的props变化影响,可以在组件挂载时把location.state的值存到自己的state里,之后用组件自身的state渲染:
修改User.jsx:
class User extends Component { constructor(props) { super(props); // 初始化时从props读取状态,设置默认值 this.state = { statusUser: props.location.state?.statusUser || 'default_status' }; } // 可选:如果需要监听props变化(比如从其他页面带不同state跳转过来) componentDidUpdate(prevProps) { if (prevProps.location.state !== this.props.location.state) { this.setState({ statusUser: this.props.location.state?.statusUser || 'default_status' }); } } render() { return ( <UserTable status={this.state.statusUser}/> ) } }
这样即使返回时location.state不存在,组件也会用自己之前保存的state值,不会报错。
总结
推荐先尝试方案1,它是最通用的错误防护手段;如果有特定的业务需求(比如必须保留状态),再考虑方案2或3。
内容的提问来源于stack exchange,提问作者Satria stuart

