如何将React项目中重复的权限判断条件逻辑抽取为独立公共组件
React权限校验逻辑模块化方案
完全可以实现,以下是两种生产环境常用的实现方式:
方案1:封装高阶组件(HOC),无侵入式替换样板代码
适合直接包裹页面组件,不需要修改原有组件内部逻辑:
// src/components/withPermission.js import { Redirect } from 'react-router-dom' // React Router v6 替换为 Navigate export default function withPermission(requiredPermissionId, WrappedComponent) { return function PermissionComponent(props) { // 统一抽离校验逻辑 const hasPermission = window.userPermission?.find( permission => permission.id === requiredPermissionId ) if (!hasPermission) { // React Router v6 写法:return <Navigate to="/" replace /> return <Redirect to="/" /> } return <WrappedComponent {...props} /> } }
使用方式
原有页面组件直接删除样板代码,导出时包裹即可:
import withPermission from 'components/withPermission' import Page1 from './Page1' function SomeComponent() { return ( <div> <Page1/> </div> ) } // 传入对应权限字符串即可 export default withPermission('Page1', SomeComponent)
方案2:封装通用权限包裹组件,灵活度更高
可以适配全场景使用,包括整页权限控制、页面内局部模块权限控制、路由层全局控制:
// src/components/RequirePermission.js import { Redirect } from 'react-router-dom' // React Router v6 替换为 Navigate import PropTypes from 'prop-types' export default function RequirePermission({ requiredPermissionId, children }) { const hasPermission = window.userPermission?.find( permission => permission.id === requiredPermissionId ) if (!hasPermission) { // React Router v6 写法:return <Navigate to="/" replace /> return <Redirect to="/" /> } return children } RequirePermission.propTypes = { requiredPermissionId: PropTypes.string.isRequired, children: PropTypes.node.isRequired }
使用方式
- 页面内使用:
import RequirePermission from 'components/RequirePermission' import Page1 from './Page1' export default function SomeComponent() { return ( <div> <RequirePermission requiredPermissionId="Page1"> <Page1 /> </RequirePermission> </div> ) }
- 路由层直接控制(推荐,页面完全不需要写权限逻辑):
// 路由配置文件 import RequirePermission from 'components/RequirePermission' import Page1 from './pages/Page1' import Page2 from './pages/Page2' const routes = [ { path: '/page1', element: <RequirePermission requiredPermissionId="Page1"><Page1 /></RequirePermission> }, { path: '/page2', element: <RequirePermission requiredPermissionId="Page2"><Page2 /></RequirePermission> } ]
额外优化建议
后续如果权限存储位置变更(比如从全局window迁移到React Context、Redux等状态管理库),只需要修改withPermission或RequirePermission这一个公共文件的权限读取逻辑即可,不需要改动所有业务页面。
内容的提问来源于stack exchange,提问作者Woodchuck
相关产品推荐
相关产品推荐

