升级react-scripts@4.0.0后类内调用Hook报rules-of-hooks错误如何解决
报错原因
react-scripts@4.0.0 升级后内置的react-hooks/rules-of-hooks校验规则覆盖场景更完善,之前能通过编译是旧版本规则没有检测到类静态方法中的违规Hook调用,本质是写法本身就违反了React Hooks的调用规则:
- React Hooks 仅允许在React函数组件顶层、自定义Hook函数顶层调用,禁止在普通JavaScript类、类的方法/静态属性、普通工具函数中调用。
- 你在
Business类的静态validationSchemagetter中直接调用自定义HookuseYup(),属于明确的规则违反,旧版本未拦截属于校验遗漏,这种写法本身就存在运行时隐患:Hook依赖的React上下文无法在类的静态方法中正常追踪更新。
修复方案
不要试图绕过ESLint校验规则,这类违规写法本身就违背Hooks设计逻辑,强行关闭规则后续大概率出现上下文不更新、状态错乱的运行时问题。按照规则调整代码结构,把Hook调用移到合法的上下文内即可,推荐改法如下:
- 移除类静态方法中的Hook调用,先清理
Business类里的违规逻辑:
import * as Yup from 'yup'; import { BusinessExpense } from './BusinessExpense.entity'; export class Business { // 其他属性定义 businessName?: string = ''; // 移除原有调用useYup的静态validationSchema逻辑 }
- 新建专门生成校验Schema的自定义Hook,把Hook调用放在合法的自定义Hook上下文中,同时用
useMemo缓存Schema避免重复渲染时重复生成:
import * as Yup from 'yup'; import { useMemo } from 'react'; import useYup from '../hooks/useYup'; import { Business } from './Business.entity'; export const useBusinessValidationSchema = () => { // 自定义Hook内调用其他Hook符合规则 const { name: businessName } = useYup(); return useMemo(() => { return Yup.object({ businessName }); }, [businessName]); };
- 在使用Formik的React函数组件顶层调用上述自定义Hook,拿到生成的校验Schema后再传入
useFormik配置:
// 注意:以下代码需要写在React函数组件/自定义Hook的顶层 const businessValidationSchema = useBusinessValidationSchema(); const { values, handleChange, errors, touched, handleSubmit } = useFormik({ initialValues: new Business(), validationSchema: businessValidationSchema, onSubmit, });
如果项目中存在大量类似的模型类需要生成校验Schema,可以把生成Schema的逻辑统一封装为对应的自定义Hook,只要不在普通类中直接调用Hook就不会触发该报错。
内容的提问来源于stack exchange,提问作者Lucas Pedroso Santos
相关产品推荐
相关产品推荐

