在 HOC React 中使用 React.createElement 避免错误 "Element type is invalid"
Avoid error "Element type is invalid" with React.createElement in HOC React
我想实现 PrivateRoute
HOC,它将检查用户是否登录然后呈现相应的组件,否则重定向到登录页面。
这是 PrivateRoute HOC:
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
const PrivateRoute = ({ component, ...rest }) => (
<Route {...rest} render={(props) => (
sessionStorage.getItem('userToken') ? (
React.createElement(component, props)
) : (
<Redirect to={{
pathname: '/login',
}} />
)
)} />
);
export default PrivateRoute;
我是这样使用的:
import PrivateRoute from './components/HOC/PrivateRoute';
...
render() {
if (this.props.hasError) return <h1>Sorry, something went wrong...</h1>;
if (this.props.isLoading) return <h1>Loading...</h1>;
return (
<div className="App">
<Switch>
<PrivateRoute exact path="/" component={<Home /> } />
<Route exact path="/login" render={props => <Login {...props} />} />
<Route exact path="/registration" render={props => <Registration {...props} />} />
<PrivateRoute exact path="/account" component={<Account />} />
</Switch>
</div>
);
}
但是报错:
我找到了一个 GitHub thread,在那里我找到了为什么会这样的可能答案,但我不知道如何为我的案例实施该答案:
我尝试了一些实验方法来实现这一点,但一切都失败了。
React.createElement
在调用 .
之前接受类型或 React 组件
React.createElement(
type,
[props],
[...children]
)
The type
argument can be either a tag name string (such as 'div' or 'span'), a React component type (a class or a function), or a React fragment type.
const Component = () => <>Hello</>;
// Good
React.createElement(Component)
React.createElement("div")
// Bad
React.createElement(<div/>)
在你的情况下,你使用的是“坏”版本。
您应该使用 cloneElement
或使用包装器修复它:
// Good
React.cloneElement(<Component />)
// Or make a wrapper
React.createElement(() => <Component />));
最后:
// Change to clone
React.cloneElement(component, props)
// **OR** make a wrapper
<PrivateRoute exact path="/" component={() => <Home />} />
我想实现 PrivateRoute
HOC,它将检查用户是否登录然后呈现相应的组件,否则重定向到登录页面。
这是 PrivateRoute HOC:
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
const PrivateRoute = ({ component, ...rest }) => (
<Route {...rest} render={(props) => (
sessionStorage.getItem('userToken') ? (
React.createElement(component, props)
) : (
<Redirect to={{
pathname: '/login',
}} />
)
)} />
);
export default PrivateRoute;
我是这样使用的:
import PrivateRoute from './components/HOC/PrivateRoute';
...
render() {
if (this.props.hasError) return <h1>Sorry, something went wrong...</h1>;
if (this.props.isLoading) return <h1>Loading...</h1>;
return (
<div className="App">
<Switch>
<PrivateRoute exact path="/" component={<Home /> } />
<Route exact path="/login" render={props => <Login {...props} />} />
<Route exact path="/registration" render={props => <Registration {...props} />} />
<PrivateRoute exact path="/account" component={<Account />} />
</Switch>
</div>
);
}
但是报错:
我找到了一个 GitHub thread,在那里我找到了为什么会这样的可能答案,但我不知道如何为我的案例实施该答案:
我尝试了一些实验方法来实现这一点,但一切都失败了。
React.createElement
在调用 .
React.createElement(
type,
[props],
[...children]
)
The
type
argument can be either a tag name string (such as 'div' or 'span'), a React component type (a class or a function), or a React fragment type.
const Component = () => <>Hello</>;
// Good
React.createElement(Component)
React.createElement("div")
// Bad
React.createElement(<div/>)
在你的情况下,你使用的是“坏”版本。
您应该使用 cloneElement
或使用包装器修复它:
// Good
React.cloneElement(<Component />)
// Or make a wrapper
React.createElement(() => <Component />));
最后:
// Change to clone
React.cloneElement(component, props)
// **OR** make a wrapper
<PrivateRoute exact path="/" component={() => <Home />} />