Я пытаюсь создать провайдер разрешений, который включает в себя глобальное состояние react-redux
. У меня есть следующее:
import React, { useCallback } from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';
export const PermissionsContext = React.createContext();
const getUserAbilities = createSelector(
state => state.user.abilities,
abilities =>
abilities.reduce((acc, val) => {
acc[val] = true;
return acc;
}, {})
);
function useAbilities() {
const abilities = useSelector(getUserAbilities);
return { abilities };
}
export const PermissionsProvider = ({ children }) => {
const { abilities } = useAbilities();
const can = useCallback((...permissions) => permissions.every(permission => permission in abilities), [
abilities
]);
return <PermissionsContext.Provider value={{ can }}>{children}</PermissionsContext.Provider>;
};
export const withPermissions = WrappedComponent => {
return class ComponentWithPermissions extends React.Component {
render() {
return (
<PermissionsContext.Consumer>
{props => <WrappedComponent {...this.props} permissions={props} />}
</PermissionsContext.Consumer>
);
}
};
};
Использование PermissionsProvider
:
<PermissionsProvider>
<App />
</PermissionsProvider>
Это включает в себя контекст, поэтому я могу useContext(PermissionsContext)
, а также HO C withPermissions
так чтобы я обернул им устаревшие class
компоненты.
В случае class
я бы назвал this.props.permissions.can('doThing1', 'doThing2')
, и он должен вернуть true
или false
в зависимости от того, все ли эти способности присутствуют в полезной нагрузке пользователя.
Кажется, что он работает нормально, за исключением случаев, когда я пытаюсь его зафиксировать, я получаю сообщение об ошибке:
React Hook "useSelector" вызывается в функции «can», который не является ни компонентом React-функции, ни пользовательской функцией React Hook-реакции-hooks / rules-hooks
Я видел несколько проблем с соглашением об именах, но, похоже, это не так применить здесь (?). Я также использовал хук useAbilities
внутри функции чуть выше функции can
, что также приводило к ошибке.
Есть идеи?