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

React渲染不同组件时触发Order of hooks错误该如何解决?

错误原因

你触发Hook顺序错误的核心问题是:你没有将步骤组件作为标准React组件渲染,而是直接调用了返回JSX的普通函数,这导致步骤函数内部的所有Hook都会被识别为父组件GenericDialog的Hook,切换步骤时不同步骤的Hook数量/顺序不一致,就会触发React的Hook规则校验告警。

具体来说,你代码里的这行写法是问题根源:

const dialogBody = steps[step]({
  setHeaderConfiguration,
  setFooterConfiguration,
});

直接调用steps[step]函数时,FirstStep里的useContext、useEffect,或者SecondStep里的useState、useEffect都会被计入GenericDialog的Hook调用链,切换步骤时Hook顺序从useRef → 6个useState → useContext → useEffect变成useRef →6个useState → useState → useEffect,自然就触发了顺序不一致的告警。

修复方案

你只需要调整两个地方,让步骤以独立React组件的形式渲染,各自的Hook归自身组件实例管理即可:

  1. 修改DialogStep的类型定义,从普通函数类型改为标准React组件类型
  2. 渲染步骤时使用JSX组件语法,而非直接调用函数

修改后的关键代码

类型定义调整

// 原来的写法
// export type DialogStep = (props: DialogStepProps) => JSX.Element;
// 改为标准组件类型
export type DialogStep = React.ComponentType<DialogStepProps>;

GenericDialog组件渲染逻辑调整

// 删掉原来直接调用函数的代码
// const dialogBody = steps[step]({
//   setHeaderConfiguration,
//   setFooterConfiguration,
// });

// 改为先取组件,再用JSX渲染
const StepComponent = steps[step];

// 渲染的地方替换成组件形式
return (
  <Dialog isShown={isShown} onHide={hideDialog}>
    <div>
      {header}
      {headerConfiguration?.subheader && (
        <Subheader>{headerConfiguration.subheader}</Subheader>
      )}
    </div>

    {isLoading && loadingMessage ? (
      <Loading msg={loadingMessage} />
    ) : (
      <StepComponent 
        setHeaderConfiguration={setHeaderConfiguration}
        setFooterConfiguration={setFooterConfiguration}
      />
    )}

    {!isLoading && (
      <DialogFooterNavigation
        onBack={isBackPossible ? onBack : undefined}
        onContinue={onContinue}
        isContinueDisabled={footerConfiguration?.isContinueDisabled}
      />
    )}
  </Dialog>
);

修改后每个步骤都是独立的React组件,内部的Hook不会影响父组件GenericDialog的Hook顺序,切换步骤时告警自然就消失了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 08:27:03