I have the following react functional component to help support authentication required routes with react-router.
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
isAuthenticated() ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: {from: props.location }
}}/>
)
)}/>
)
I need to convert this from a functional component to a class component so I can take advantage of the componentDidMount method of React.Component. Unfortunately I'm having trouble figuring out how to migrate this. If I take it as is I need to replicate the Component and ...rest parameters, but I'm not sure how to do that. I think I can get the Component parameter with this.props.component, but I'm not sure how to pull ...rest. I'm new to JSX and ES6 so any help or guidance would be much appreciated.
There isn't anything difficult really. The functional component is the render function, therefore:
class PrivateRoute extends React.Component {
render() {
const {component: Component, ...rest} = this.props;
return (
<Route {...rest} render={props => (
isAuthenticated() ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: {from: props.location }
}}/>
)
)}/>
);
}
}
or, written a bit more readable:
class PrivateRoute extends React.Component {
render() {
const {component: Component, ...rest} = this.props;
const renderRoute = props => {
if (isAuthenticated()) {
return (
<Component {...props} />
);
}
const to = {
pathname: '/login',
state: {from: props.location}
};
return (
<Redirect to={to} />
);
}
return (
<Route {...rest} render={renderRoute}/>
);
}
}
A nice, clean refactor by extending the Route component:
class PrivateRoute extends Route {
render() {
return isAuthenticated()
? super.render()
: <Redirect to={{
pathname: '/login',
state: {from: props.location}
}}/>;
}
}
If you use this, you have to wrap your <PrivateRoute/>s in a <Switch/>, as below. Otherwise, you will have duplicate redirects and the page will fail to load.
<Router>
<Navbar/>
<SideDrawer/>
<Switch>
<Route path="/tokens" component={Login}/>
<PrivateRoute exact path="/" component={ExampleComponent}/>
<PrivateRoute path="/users" component={Users}/>
<PrivateRoute path="/software" component={Software}/>
</Switch>
</Router>
来源:https://stackoverflow.com/questions/43695583/converting-react-function-component-to-class-component-issue