Vitest测试React报错Cannot read properties of null (reading 'useRef')
问题根因
TypeError: Cannot read properties of null (reading 'useRef')以及后续出现的useReducer实例为null报错,和react-hook-form本身逻辑、测试库版本兼容没有关系,核心原因是Vitest运行测试时加载了多份重复的React实例,hooks调用时无法匹配到当前组件对应的React上下文,才会读取到null值。
开发环境下Vite的依赖预构建逻辑会自动统一React的引用路径,所以正常跑项目不会触发问题,只有测试环境的模块解析逻辑和开发环境不一致时才会暴露这个问题。
修复步骤
按顺序操作即可解决:
- 第一步:修改
vite.config.js配置,强制所有场景下React相关依赖都解析到本地node_modules里的单份实例,同时配置Vitest预构建React生态相关依赖,从根源避免多副本问题。修改后的配置如下:
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import path from 'path' // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], resolve: { alias: { react: path.resolve('./node_modules/react'), 'react-dom': path.resolve('./node_modules/react-dom') } }, test: { globals: true, environment: 'jsdom', setupFiles: './src/setupTests.js', deps: { inline: ['react', 'react-dom', 'react-hook-form', 'react-router-dom'] } } })
- 第二步:清理缓存和旧依赖后重新安装,避免历史预构建缓存导致配置不生效:
# 删除依赖目录和Vitest缓存 rm -rf node_modules .vitest # 按自己使用的包管理工具删除对应锁文件:npm删package-lock.json,pnpm删pnpm-lock.yaml,yarn删yarn.lock rm package-lock.json # 重新安装依赖 npm install
- 第三步:检查所有测试用例的写法,所有React组件必须通过
@testing-library/react提供的render方法挂载,禁止直接裸调用组件函数。错误写法const result = Login()会直接让组件脱离React上下文运行,必然触发hooks报错,正确写法为render(<Login />)。
不需要额外安装
@testing-library/react-hooks,React 18的适配逻辑已经内置在@testing-library/react@13及以上版本中,安装旧版的独立hooks测试库反而会引入额外的React副本,加重多实例问题。
完成以上操作后重新运行npm run test即可正常执行测试。
内容的提问来源于stack exchange,提问作者A-PSquestions
相关产品推荐
相关产品推荐

