高阶组件抛出无效的反应元素错误(reactjs)
high order component throws an invalid react element error (reactjs)
所以我最近一直在阅读 HOC 并决定在我的应用程序中使用它们来将授权逻辑传递给子组件。
我正在尝试通过 HOC 呈现 <Route />
组件,但它记录了错误:
Uncaught Error: AuthRoute(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
这是 HOC 的代码:
const AuthRoute = ({ component: Component }) => {
class AuthComponent extends Component {
// Authorisation logic here
render() {
return (
<Route render={props => <Component {...props}/>} />
)
}
}
return AuthComponent;
};
然后我将此 HOC 用作 <Route />
组件的别名,如下所示:
<BrowserRouter>
<AuthRoute path="/account" component={PrivateComponent} />
</BrowserRouter>
编辑:
但这种方法效果很好:
const AuthRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
checkAuth() ? (<Component {...props}/>) : (<Redirect to={{pathname: '/', state: { from: props.location }}}/>)
)}/>
);
<BrowserRouter>
<AuthRoute path="/account" component={PrivateComponent} />
</BrowserRouter>
您需要检查您的体系结构。实际上,关于 HOC 模式,您的方法完全矛盾。您可能需要改为执行以下操作:
<BrowserRouter>
<Route path="/account" component={AuthRoute(PrivateComponent)} />
</BrowserRouter>
如果您同意这种调用 HOC 的设计,则 HOC 实现将是:
const AuthRoute = (Composed) => {
class AuthComponent extends React.Component {
// Authorisation logic here
componentWillMount() {
if (!checkAuth()) {
this.props.history.push({pathname: '/', state: { from: this.props.location }});
}
}
render() {
return (
<Composed {...this.props} />
)
}
}
return AuthComponent;
};
我不是很熟悉你写的语法。但是发现了一件事。您的参数是 component 但在内部您使用的是 Component 在这种情况下未定义
应该是:
const AuthRoute = (Component ) => { // <-- Component which refers to PrivateComponent
class AuthComponent extends React.Component { // <-- React.Component
....
而不是:
const AuthRoute = ({ component: Component }) => {
class AuthComponent extends Component {
...
另请查看 以获得优雅的 HOC。
在第一种情况下,您将返回一个 class 实例
const AuthRoute = ({ component: Component }) => {
class AuthComponent extends Component {
// Authorisation logic here
render() {
return (
<Route render={props => <Component {...props}/>} />
)
}
}
return AuthComponent; // returning the class object here and not an instance
};
所以如果你想使用它,你需要写
<BrowserRouter>
<Route path="/account" component={AuthRoute(PrivateComponent)} />
</BrowserRouter>
其中 AuthRoute(PrivateComponent)
是一个 class 对象,Route 在内部创建一个实例
但是在第二种情况下,它不是 HOC,而是一个 returns 有效 React 元素的功能组件,
const AuthRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
checkAuth() ? (<Component {...props}/>) : (<Redirect to={{pathname: '/', state: { from: props.location }}}/>)
)}/>
);
因此
使用 <AuthRoute path="/account" component={PrivateComponent} />
,您调用了一个组件实例,其中功能组件接收道具 path
和 component
。
所以我最近一直在阅读 HOC 并决定在我的应用程序中使用它们来将授权逻辑传递给子组件。
我正在尝试通过 HOC 呈现 <Route />
组件,但它记录了错误:
Uncaught Error: AuthRoute(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
这是 HOC 的代码:
const AuthRoute = ({ component: Component }) => {
class AuthComponent extends Component {
// Authorisation logic here
render() {
return (
<Route render={props => <Component {...props}/>} />
)
}
}
return AuthComponent;
};
然后我将此 HOC 用作 <Route />
组件的别名,如下所示:
<BrowserRouter>
<AuthRoute path="/account" component={PrivateComponent} />
</BrowserRouter>
编辑:
但这种方法效果很好:
const AuthRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
checkAuth() ? (<Component {...props}/>) : (<Redirect to={{pathname: '/', state: { from: props.location }}}/>)
)}/>
);
<BrowserRouter>
<AuthRoute path="/account" component={PrivateComponent} />
</BrowserRouter>
您需要检查您的体系结构。实际上,关于 HOC 模式,您的方法完全矛盾。您可能需要改为执行以下操作:
<BrowserRouter>
<Route path="/account" component={AuthRoute(PrivateComponent)} />
</BrowserRouter>
如果您同意这种调用 HOC 的设计,则 HOC 实现将是:
const AuthRoute = (Composed) => {
class AuthComponent extends React.Component {
// Authorisation logic here
componentWillMount() {
if (!checkAuth()) {
this.props.history.push({pathname: '/', state: { from: this.props.location }});
}
}
render() {
return (
<Composed {...this.props} />
)
}
}
return AuthComponent;
};
我不是很熟悉你写的语法。但是发现了一件事。您的参数是 component 但在内部您使用的是 Component 在这种情况下未定义
应该是:
const AuthRoute = (Component ) => { // <-- Component which refers to PrivateComponent
class AuthComponent extends React.Component { // <-- React.Component
....
而不是:
const AuthRoute = ({ component: Component }) => {
class AuthComponent extends Component {
...
另请查看
在第一种情况下,您将返回一个 class 实例
const AuthRoute = ({ component: Component }) => {
class AuthComponent extends Component {
// Authorisation logic here
render() {
return (
<Route render={props => <Component {...props}/>} />
)
}
}
return AuthComponent; // returning the class object here and not an instance
};
所以如果你想使用它,你需要写
<BrowserRouter>
<Route path="/account" component={AuthRoute(PrivateComponent)} />
</BrowserRouter>
其中 AuthRoute(PrivateComponent)
是一个 class 对象,Route 在内部创建一个实例
但是在第二种情况下,它不是 HOC,而是一个 returns 有效 React 元素的功能组件,
const AuthRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
checkAuth() ? (<Component {...props}/>) : (<Redirect to={{pathname: '/', state: { from: props.location }}}/>)
)}/>
);
因此
使用 <AuthRoute path="/account" component={PrivateComponent} />
,您调用了一个组件实例,其中功能组件接收道具 path
和 component
。