如何无需逐个控制函数实现权限校验?React RBAC方案咨询
无侵入式RBAC操作权限校验实现方案
一、核心权限校验工具层
先实现全局统一的权限判断逻辑,避免重复代码:
// src/utils/permission.js import { useContext } from 'react'; import { AuthContext } from '../contexts/AuthContext'; export const usePermission = () => { const { user } = useContext(AuthContext); const userPermissions = user?.permissions || []; // 判断是否拥有指定操作权限 const hasPermission = (action) => { return userPermissions.includes(action); }; return { hasPermission }; };
二、封装权限控制的通用按钮组件
替代原生MUI Button,自动处理权限校验,同时解决禁用后可点击的问题:
// src/components/PermissionButton.js import { Button } from '@mui/material'; import { usePermission } from '../utils/permission'; const PermissionButton = ({ action, children, ...props }) => { const { hasPermission } = usePermission(); const isAllowed = hasPermission(action); // 无权限时禁用并添加防点击样式,彻底阻止交互 const buttonProps = isAllowed ? props : { ...props, disabled: true, sx: { ...props.sx, pointerEvents: 'none', opacity: 0.6 } }; // 也可选择无权限时直接隐藏组件,替换上面的return即可 // if (!isAllowed) return null; return <Button {...buttonProps}>{children}</Button>; }; export default PermissionButton;
使用示例:
<PermissionButton action="add" onClick={addData}>新增设备</PermissionButton> <PermissionButton action="edit" onClick={editData}>编辑设备</PermissionButton> <PermissionButton action="delete" onClick={deleteData}>删除设备</PermissionButton>
三、函数级权限拦截高阶函数
对业务操作函数做统一包装,无需逐个加if判断:
// src/utils/permissionHOC.js import { usePermission } from './permission'; import { useSnackbar } from '@mui/material'; // 高阶函数:传入权限标识,返回包装后的函数 export const withPermission = (action) => (fn) => { const { hasPermission } = usePermission(); const { enqueueSnackbar } = useSnackbar(); return (...args) => { if (!hasPermission(action)) { enqueueSnackbar('无此操作权限', { variant: 'error' }); return; } // 有权限时执行原函数 return fn(...args); }; };
使用示例:
import { withPermission } from '../utils/permissionHOC'; const DevicesPage = () => { // 原业务函数 const addData = () => { /* 新增设备逻辑 */ }; const editData = () => { /* 编辑设备逻辑 */ }; const deleteData = () => { /* 删除设备逻辑 */ }; // 用高阶函数包装,自动添加权限校验 const authorizedAdd = withPermission('add')(addData); const authorizedEdit = withPermission('edit')(editData); const authorizedDelete = withPermission('delete')(deleteData); return ( <> <PermissionButton action="add" onClick={authorizedAdd}>新增设备</PermissionButton> {/* 即使使用普通按钮,点击也会被权限拦截 */} <Button onClick={authorizedEdit}>编辑设备</Button> </> ); };
四、补充:彻底解决MUI Button禁用交互问题
如果封装组件后仍有问题,可全局添加CSS样式确保禁用状态完全不可交互:
/* src/index.css */ .MuiButton-disabled { pointer-events: none !important; cursor: not-allowed !important; }
内容的提问来源于stack exchange,提问作者Furkan YIlmaZ
相关产品推荐
相关产品推荐

