My Goal:
I'm currently implementing an AuthUserRole
HOC component to handle the user roles: Manager and Employee. I'm using this tutorial to do so, but they use a functional component to return a class component.
My Question:
How can I write this HOC functional component to return a functional component instead of a class component? Or is there a better way?
Functional Component That Returns A Class Component:
// Imports: Dependencies
import React, { Component } from 'react';
import { connect } from 'react-redux';
// Component: Authorization
const AuthUserRole = (WrappedComponent, allowedRoles) => {
class With AuthUserRole extends Component {
render() {
const userType = this.props.userType;
if (allowedRoles.includes(userType)) {
return <WrappedComponent {...this.props} />;
}
else {
return <h1>You are not allowed to view this page!</h1>;
}
}
}
const mapStateToProps = state => ({ user: state.login.userName, userType: state.login.userType });
return connect(mapStateToProps)(AuthUserRole);
};
// Exports
export default AuthUserRole;
App.js (Where HOC Is Used):
<BrowserRouter history={history}>
<Switch>
{/* LANDING */}
<Route path="/" component={Landing} exact />
{/* APP */}
<PrivateRoute path="/student/dashboard" component={Authorization(DashboardStudent,["Student"])}/>
<PrivateRoute path="/admin/dashboard" component={Authorization(DashboardAdmin,["Admin"])}/>
{/* LOGIN */}
<Route path="/login" component={UserLogin}/>
{/* NOT FOUND */}
<Route path="" component={NotFoundPage} />
</Switch>
</BrowserRouter>
In order to return a function component, just return a function of props
const AuthUserRole = (WrappedComponent, allowedRoles) => {
return (props) => {
...
}
}
The recommended best practice is to use the useSelector
hook instead of mapStateToProps
and connect
. So there are some other tweaks.
import React, { ComponentType } from 'react';
import { useSelector } from 'react-redux';
// Component: Authorization
const AuthUserRole = <Props extends {}>(WrappedComponent: ComponentType<Props>, allowedRoles: string[]) => {
return (props: Props) => {
// TODO: add your app's state type
const userType = useSelector(state => state.login.userType);
const user = useSelector(state => state.login.userName); // where is this used?
if (allowedRoles.includes(userType)) {
return <WrappedComponent {...props} />;
}
else {
return <h1>You are not allowed to view this page!</h1>;
}
}
};
// Exports
export default AuthUserRole;
I added type annotations because you tagged this typescript
, but I don't see any types in the current code.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.