前端如何根据ACL动态控制按钮显示?

宇文晓英 阅读 15

我们后端返回的用户权限是类似 {"user:delete": true, "post:edit": false} 这样的ACL结构。现在我想在React组件里根据这个权限决定“删除用户”按钮要不要渲染,但不确定怎么设计才不会让组件到处都是判断逻辑。

我试过在每个按钮外面包一层检查函数,但感觉很重复。有没有更优雅的方式?比如用高阶组件或者自定义Hook?

const hasPermission = (action) => {
  return userAcl[action] === true;
};

// 在组件里
{hasPermission('user:delete') && <button>删除用户</button>}
我来解答 赞 4 收藏
二维码
手机扫码查看
1 条解答
轩辕一诺
你现在的写法确实会让权限判断逻辑散落得到处都是,后期维护起来很痛苦。这个问题我之前也踩过坑,分享几个实用的方案。

最推荐的是封装一个权限组件,把判断逻辑收敛到一个地方:

import { createContext, useContext } from 'react';

const PermissionContext = createContext({});

export const PermissionProvider = ({ acl, children }) => {
return (

{children}

);
};

export const usePermission = () => {
const acl = useContext(PermissionContext);
return (action) => acl[action] === true;
};

// 权限控制组件
export const Authorized = ({ permission, fallback, children }) => {
const hasPermission = usePermission();

if (!permission) return children;

return hasPermission(permission) ? children : (fallback || null);
};


在应用入口挂载Provider:

function App() {
const [acl, setAcl] = useState({});

useEffect(() => {
fetchUserAcl().then(setAcl);
}, []);

return (



);
}


组件里用起来就很干净了:

import { Authorized } from './permission';

function UserList() {
return (





无权限}>



);
}


如果你嫌组件嵌套太深,也可以直接用Hook:

function UserList() {
const can = usePermission();

return (

{can('user:delete') && }

);
}


两种方式可以混着用,简单判断用Hook,复杂的或者需要fallback的场景用Authorized组件。

高阶组件的方式也可以,但现在Hooks更主流,HOC容易造成嵌套地狱,不太推荐了。

还有个坑要注意,权限数据一定要在组件渲染前准备好,不然会闪一下未授权的UI。可以在Provider外层加个loading状态,或者用Suspense处理。
点赞 2
2026-03-01 10:38