React条件配置单用户导航时触发Invalid hook call错误
报错原因
触发Invalid hook call是因为违反了React Hooks的基础调用规则:Hooks仅允许在React函数组件、自定义Hook的顶层作用域调用。你的navconfig.js是普通JS模块,不是函数组件也不是自定义Hook,直接在模块顶层调用useState、useSelector、useEffect必然触发该报错。
除此之外你的代码还存在两个逻辑BUG:
useEffect回调内用const声明的navConfig是块级作用域变量,外部无法访问,即使Hook不报错也拿不到正确的导出值- 定义了完全未使用的
email、password状态,属于冗余代码
修复代码
推荐将导航配置封装为自定义Hook,既符合Hooks调用规则,也方便在组件中复用:
import { useMemo } from 'react'; import { useSelector } from 'react-redux'; import Iconify from '../../components/Iconify'; const getIcon = (name) => <Iconify icon={name} width={22} height={22} />; export function useNavConfig() { const { currentUser } = useSelector((state) => state.user); return useMemo(() => { const userEmail = currentUser ? JSON.parse(currentUser).email : null; // 公共导航菜单,所有用户可见 const publicMenus = [ { title: 'user', path: '/dashboard/user', icon: getIcon('eva:people-fill'), }, { title: 'product', path: '/dashboard/products', icon: getIcon('eva:shopping-bag-fill'), }, { title: 'blog', path: '/dashboard/blog', icon: getIcon('eva:file-text-fill'), }, { title: 'calender', path: '/dashboard/calender', icon: getIcon('uis:calender'), }, { title: 'login', path: '/login', icon: getIcon('eva:lock-fill'), }, { title: 'register', path: '/register', icon: getIcon('eva:person-add-fill'), }, { title: 'Not found', path: '/404', icon: getIcon('eva:alert-triangle-fill'), }, ]; // 目标专属用户追加dashboard菜单 if (userEmail === "lokesh.kanhasoft@gmail.com") { return [ { title: 'dashboard', path: '/dashboard/app', icon: getIcon('eva:pie-chart-2-fill'), }, ...publicMenus ]; } return publicMenus; }, [currentUser]); }
使用方式
在渲染导航栏/侧边栏的函数组件顶层直接调用即可:
const navConfig = useNavConfig(); // 后续直接遍历navConfig渲染菜单项
避坑提醒
- 不要在普通JS模块、条件分支、循环、嵌套函数内部调用React Hooks
- 不要在
useEffect这类副作用回调里定义需要跨作用域访问、导出的变量,这类变量仅在回调执行时存在 - 相等判断优先用严格相等
===,避免==隐式类型转换导致的权限判断逻辑异常
内容的提问来源于stack exchange,提问作者Lokesh Bhardwaj
相关产品推荐
相关产品推荐

