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

React项目从RTK迁移到Rematch时主题切换触发Invalid Hook call错误

错误原因

核心问题是违反了React Hook的使用规则:所有Hook必须在React函数组件的顶层作用域调用,不能在普通回调函数、嵌套函数、条件分支、循环语句中调用。
你定义的DispatchThemes是传递给ThemeSwitcher的事件回调函数,只有用户切换主题开关时才会触发执行,此时函数执行上下文不属于组件渲染的顶层流程,因此函数内部调用的useDispatch和useEffect两个Hook都不符合调用规则,直接触发Invalid hook call报错。

修复方案

完全不需要在回调函数中调用Hook,按如下步骤修改Navigation组件即可:

  1. 在Navigation组件的顶层(和其他Hook同层级)调用useDispatch拿到全局dispatch实例
  2. 把DispatchThemes改写为无Hook的普通事件处理函数,内部直接调用dispatch方法更新store
  3. 将改写后的处理函数传递给ThemeSwitcher的themeChanger属性

修复后的Navigation组件核心代码示例

const Navigation: React.FC = () => {
  // 其他原有代码保持不变
  // 1. 组件顶层调用useDispatch,符合Hook规则
  const dispatch = useDispatch<Dispatch>()

  // Get OS-level preference for dark mode
  const prefersDarkMode: boolean | undefined = useMediaQuery("(prefers-color-scheme: dark)");

  // 2. 改写为普通事件处理函数,无任何Hook调用
  const changeTheme = (themeMode: boolean | undefined) => {
    dispatch.themeModel.setDarkModeAsync(themeMode);
  }

  return (
    {/* 其他原有代码保持不变 */}
    {/* 3. 传递改写后的处理函数 */}
    <ThemeSwitcher useOs={false} themeChanger={changeTheme} />
    {/* 其他原有代码保持不变 */}
  );
}

你原来的代码中额外加的useEffect属于冗余逻辑,你的需求是用户切换开关时立即触发store更新,不需要等待副作用执行,直接调用dispatch即可。

内容的提问来源于stack exchange,提问作者Simon Mayrhofer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 22:57:03