React中使用状态变量条件声明对象数组报Hook错误如何解决
React Hook调用报错修复方案
报错根因
你触发hooks can only be used inside body of functions错误的核心原因是违反了React Hook的强制调用规则:
- 所有React Hook(包括你封装的读取全局上下文的
AppState())仅允许在React函数组件、自定义Hook的顶层作用域内调用 - 你当前的代码在模块顶层直接执行
IsLoggedIn()触发Hook调用,既不在React组件上下文内,也不符合自定义Hook的执行要求,因此直接抛错。
除此之外你当前的实现还有逻辑缺陷:routes是模块加载时就生成的静态常量,就算绕开报错,show字段的值也只会在页面首次加载时计算一次,后续用户登录、登出的状态变化不会同步更新路由配置,无法实现动态显示/隐藏菜单的需求。
另外你原本的登录判断逻辑写反了:user === null代表用户未登录,和你「已登录才显示Put Rating」的需求正好相反。
正确实现方式
不要在模块顶层静态定义依赖登录状态的路由配置,把路由配置的生成逻辑封装为自定义Hook,保证状态变化时路由配置可以同步更新:
- 修改路由配置文件,封装自定义Hook返回动态路由数组
import { AppState } from '../AppContext'; export function useFilteredRoutes() { // 在自定义Hook顶层调用状态Hook,符合调用规则 const { user } = AppState(); // 每次user状态变化时,自动返回最新的路由配置 return [ { title: "home page", show: true, }, { title: "put rating", // 修正判断逻辑:用户已登录(user不为null)时才显示 show: user !== null, } ]; }
- 在你渲染导航菜单/路由列表的组件中,调用上述自定义Hook拿到路由配置,过滤后渲染即可:
import { useFilteredRoutes } from './路由配置文件路径'; function Navigation() { // 在组件顶层调用自定义Hook,符合Hook调用规则 const routes = useFilteredRoutes(); return ( <div className="nav-list"> {routes .filter(route => route.show) .map(route => ( <div className="nav-item" key={route.title}> {route.title} </div> )) } </div> ); }
内容的提问来源于stack exchange,提问作者Balaji
相关产品推荐
相关产品推荐

