使用本地React npm包时出现TypeError: Cannot read properties of null (reading 'useState')
TypeError: Cannot read properties of null (reading 'useState')错误 这个错误通常是因为React实例重复加载导致的——你的组件包和宿主项目使用了两个不同的React副本,而React Hooks要求必须在同一个React实例环境下运行。结合你的Webpack配置和使用场景,按以下步骤排查修复:
1. 删除Webpack配置中React相关的resolve alias
你当前的resolve.alias强制组件包使用自身node_modules里的React,这会导致宿主项目和组件包的React实例不一致。直接移除这两行:
// webpack.config.js - 移除以下内容 alias: { react: path.resolve(__dirname, "node_modules/react"), "react-dom": path.resolve(__dirname, "node_modules/react-dom"), },
2. 在package.json中声明peerDependencies
确保你的组件包不会自带React,而是依赖宿主项目提供的React实例。在包的package.json中添加:
"peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "react": { "optional": false }, "react-dom": { "optional": false } }
这样npm会确保宿主项目安装了兼容版本的React,且组件包会复用宿主的React实例。
3. 验证Webpack externals配置(当前配置正确但需确认)
你当前的externals配置已经正确将React和ReactDOM标记为外部依赖,打包时不会把它们打包进组件包的bundle里。可以检查dist/index.js文件,确认没有包含React的源码(正常应该是通过require('react')或import React from 'react'引用外部依赖)。
4. 本地测试时解决npm link的符号链接问题
如果是用npm link本地测试组件包,可能会因为符号链接导致组件包读取自身node_modules的React。此时需要在宿主项目的配置中添加resolve alias,强制指向宿主自己的React:
// 宿主项目的webpack.config.js resolve: { alias: { react: path.resolve(__dirname, 'node_modules/react'), 'react-dom': path.resolve(__dirname, 'node_modules/react-dom') } }
或者改用npm pack生成tar包,然后在宿主项目中通过npm install ../path/to/your-package.tgz本地安装,避免符号链接问题。
5. 检查TypeScript配置
确保包的tsconfig.json中JSX配置正确,并且生成类型声明:
{ "compilerOptions": { "target": "es5", "module": "esnext", "lib": ["dom", "dom.iterable", "esnext"], "jsx": "react-jsx", // React 17+ 用这个,React 16用"react" "declaration": true, // 生成.d.ts类型文件 "declarationDir": "./dist", "outDir": "./dist", "strict": true, "moduleResolution": "node", "esModuleInterop": true }, "include": ["src"], "exclude": ["node_modules", "dist"] }
完成以上步骤后,重新打包组件包并在宿主项目中测试,应该可以解决useState读取null的错误。
内容的提问来源于stack exchange,提问作者Guna

