You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用useContext从函数组件更新类组件状态时触发无效钩子调用错误

问题分析与修复方案

你遇到的invalid hook call错误,核心原因是违反了React钩子的使用规则:钩子只能在函数组件的顶层作用域调用,不能嵌套在其他函数(比如点击事件回调)里。

看你的Home组件代码,ContextMenuId是一个嵌套函数,你在里面调用了useContext(AppContext),这直接触发了钩子调用错误。


修复步骤

  1. 将useContext移到组件顶层:提前在Home组件的最外层获取上下文对象,不要等到点击事件触发时才调用钩子。
  2. 不要直接修改上下文属性:上下文里的route来自App组件的state,不能直接赋值修改,应该通过App提供的updateMenuId方法让父组件自己更新state。
  3. 修正App组件的路由更新逻辑:原updateMenu方法里把route设为字符串'menu',但原有state里route是parseRoute返回的对象(含path属性),需保持格式一致,避免后续路由判断出错。

修正后的关键代码

Home组件(核心修改部分)

export default function Home() {
  // 把useContext移到组件顶层,符合钩子使用规则
  const context = useContext(AppContext);
  const [locations, setLocations] = useState({ locations: ['no results'] });
  const searchInput = useRef(null);

  // ... 其余原有代码保持不变 ...

  // 重构点击处理函数,直接使用顶层获取的上下文
  const handleMenuClick = (id) => {
    // 调用App提供的方法更新状态,不直接修改上下文属性
    context.updateMenuId(id);
    console.log('Id', id);
  };

  // ... 其余原有代码保持不变 ...

  // 在渲染按钮时,调用重构后的处理函数
  // 示例(LocSetup函数内的按钮):
  <button onClick={() => handleMenuClick(location.brand_id)}>
    Link to items on menu under 500 calories
  </button>
}

App组件(修正路由更新逻辑)

updateMenu(id) {
  // 保持route为parseRoute返回的对象格式,和初始化逻辑一致
  this.setState({ route: parseRoute('#menu'), menuId: id });
}

内容的提问来源于stack exchange,提问作者Giancarlo Massoni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 21:20:29