React路由鉴权报错:Class constructor App cannot be invoked without 'new'求解决
解决React高阶组件报错:Class constructor App cannot be invoked without 'new'
这个报错的根源很明确——你的高阶组件RequireAuth的写法有个隐藏前提:它假设传入的Component是一个类组件,但如果你的Profile是函数组件的话,就会触发这个错误。
为什么会报错?
你写的class App extends Component里,Component是你传入的Profile组件。如果Profile是函数组件,那这里的Component就是一个普通函数,而ES6类只能继承另一个类(比如React.Component),不能继承函数。当React尝试实例化这个App类时,就会抛出"不能不用new调用构造函数"的错误,因为你继承的不是合法的类构造函数。
修复方案1:修改类继承的目标
把继承的对象从传入的Component改成React.Component,这样不管你传入的是类组件还是函数组件,都能正常工作:
import React from 'react'; const RequireAuth = (Component) => { // 这里改成继承React.Component,而不是传入的Component return class App extends React.Component { componentDidMount() { // 注意:componentWillMount已过时,建议用componentDidMount const getToken = localStorage.getItem('token'); if(!getToken) { this.props.history.replace({pathname: '/'}); } } render() { return <Component {...this.props} /> } } } export { RequireAuth };
修复方案2:改用函数式高阶组件(推荐)
现代React更推荐用函数式组件来写高阶组件,不仅避免了类继承的问题,还能使用更简洁的Hook API:
import React, { useEffect } from 'react'; import { useHistory } from 'react-router-dom'; const RequireAuth = (Component) => { return (props) => { const history = useHistory(); useEffect(() => { const getToken = localStorage.getItem('token'); if(!getToken) { history.replace({pathname: '/'}); } }, [history]); // 依赖数组确保只在history变化时执行 return <Component {...props} />; } } export { RequireAuth };
额外提醒
componentWillMount已经被React标记为过时的生命周期方法,存在潜在的问题(比如服务器渲染时可能执行多次),建议改用componentDidMount(类组件)或useEffect(函数组件)。- 如果你正在使用React Router v6,
PrivateRoute的写法已经和v5不同,但你的当前写法是v5风格,上面的修复方案也能适配v6(只需要调整PrivateRoute的定义即可)。
内容的提问来源于stack exchange,提问作者ScreamX
相关产品推荐
相关产品推荐

