I am writing a custom functional component called Can
which takes two arguments (an action identifier and a callback function to be used if access is denied) that can wrap other components and essentially checks if a user has access.
The component is as follows (the console.log
statements are there for debugging and become important later):
const Can = (props) => {
console.log("Can Component is executed");
const roles = useSelector((state) => state.common.user.roles);
roles.forEach((element) => {
if (check(rules, element, props.perform, props.data)) {
console.log(
"Check matched for Role" + element + " - it can do " + props.perform
);
return <>{props.children}</>;
}
});
console.log(
"No match found for the current user to perform " + props.perform
);
return props.no();
};
The user has multiple roles (stored in the application wide state) and for each of these roles access is checked. Once a role grants access, it is supposed to return the children
prop, otherwise it will return the no
prop being the mentioned callback.
It is called as follows:
<Can perform={"ui:see_admin"} no={() => <h2>NoAccess</h2>}>
<br />
<b>Administration</b>
<NavLink to="/admin/user">
<UserAction>
Benutzerverwaltung
<span style={{ float: "right" }}>Coming soon</span>
</UserAction>
</NavLink>
</Can>
The problem I have is that even if the check
function matches, the no()
action is returned. The output in the console is:
- Can Component is executed
- Check matched for Role xxx - it can do yyy
- No match found for the current user to perform xxx
And then props.no()
is returned. Why does this happen?