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归自身组件实例管理即可:
- 修改
DialogStep的类型定义,从普通函数类型改为标准React组件类型 - 渲染步骤时使用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
相关产品推荐
相关产品推荐

