如何在Next.js的webpack中将react-hook-form设为外部库解决useFormContext空值报错
react-hook-form useFormContext 返回null 报错解决方案
- 第一步:优先排查FormProvider包裹
这是该报错90%以上场景的触发原因:useFormContext仅可在FormProvider组件包裹的子组件树内调用。你需要先在表单的父层组件调用useForm获取方法,再将整个表单区域用FormProvider透传所有方法,示例代码如下:
// 表单父组件 import { useForm, FormProvider } from 'react-hook-form'; import DropzoneField from './DropzoneField'; export default function FormPage() { const formMethods = useForm(); return ( <FormProvider {...formMethods}> <form onSubmit={formMethods.handleSubmit((data) => console.log(data))}> {/* 你调用useFormContext的子组件要放在FormProvider内部 */} <DropzoneField /> <button type="submit">提交</button> </form> </FormProvider> ) }
子组件内即可正常解构出control属性:
// DropzoneField.tsx import { useFormContext, Controller } from 'react-hook-form'; import { useDropzone } from 'react-dropzone'; export default function DropzoneField() { const { control } = useFormContext(); // 后续逻辑 }
普通业务开发场景下完成这一步即可解决问题,无需修改webpack配置。你看到的修改externals的解决方案仅适用于开发npm公共组件库的特殊场景。
- 第二步:排查react-hook-form多实例问题
如果确认已经正确包裹FormProvider仍然报错,大概率是项目中存在多个版本的react-hook-form实例,导致上下文不互通。
执行以下命令查看依赖版本:
# npm npm ls react-hook-form # pnpm pnpm ls react-hook-form # yarn yarn list react-hook-form
如果输出中存在多个版本的react-hook-form,在package.json中添加版本锁定配置后重新安装依赖即可:
// npm 场景添加overrides { "overrides": { "react-hook-form": "你项目中安装的版本号,比如7.45.0" } }
// yarn/pnpm 场景添加resolutions { "resolutions": { "react-hook-form": "你项目中安装的版本号,比如7.45.0" } }
- 第三步:仅公共组件库开发场景需要修改webpack配置
如果你确实是在开发基于Next.js的公共组件库,需要配置externals的话,要区分服务端和客户端环境,修改配置如下:
// next.config.js module.exports = { webpack: (config, { isServer }) => { // 仅客户端构建时external react-hook-form if (!isServer) { config.externals.push({ 'react-hook-form': 'window.ReactHookForm' }) } return config } }
注意该配置需要配合在html全局引入react-hook-form的UMD包,否则客户端会找不到对应的全局变量。
内容的提问来源于stack exchange,提问作者Renato Willyan
相关产品推荐
相关产品推荐

