发布React组件包测试报错:无法读取null的'useState'属性
React组件包测试时出现useState读取null的错误
问题描述
跟随@alexeagleson的教程发布了@okafohenry/react-custom-select组件包,但在其他项目中测试该组件时,组件无法正常显示,且抛出错误:
Uncaught TypeError: cannot read property of null (reading 'useState')
组件包package.json
{ "name": "@okafohenry/react-custom-select", "version": "0.0.12", "description": "Custom-select: A react component library", "scripts": { "rollup": "rollup -c" }, "author": "Henry Okafor", "license": "ISC", "devDependencies": { "@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-typescript": "^11.0.0", "@types/react": "^18.0.28", "react": "^18.2.0", "rollup": "^3.20.0", "rollup-plugin-dts": "^5.3.0", "tslib": "^2.5.0", "typescript": "^5.0.2" }, "dependencies": { "react-icons": "^4.8.0" }, "main": "dist/cjs/index.js", "module": "dist/esm/index.js", "files": [ "dist" ], "types": "dist/index.d.ts", "publishConfig": { "registry": "https://npm.pkg.github.com/okafohenry" } }
组件代码片段
import React, { useState } from "react"; const CustomSelect = (props: PropsData) => { const [ dropdownToggle, setDropdownToggle ] = useState<boolean>(false); return(/* 组件内容 */) }
原因分析
这个错误的核心原因是组件包打包时将React包含进了产物,导致测试项目中同时存在两个React实例:项目自身的React和组件包里的React。React Hook的运行依赖同一个React实例的内部状态,多个实例共存时,Hook无法正确获取上下文,从而抛出"读取null的属性"错误。
你的package.json虽然把React放在了devDependencies,但Rollup默认未配置external选项,导致打包时依然将React代码打包进了dist文件。
修复步骤
- 添加peerDependencies声明
在package.json中添加peerDependencies,明确组件包依赖React但不自带,由使用该包的项目提供:
"peerDependencies": { "react": "^18.0.0", "@types/react": "^18.0.0" }
确保react和@types/react仅保留在devDependencies中,不要移到dependencies。
- 配置Rollup external选项
修改或创建rollup.config.js,添加external配置告诉Rollup不要打包React相关依赖:
import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import typescript from '@rollup/plugin-typescript'; import dts from 'rollup-plugin-dts'; export default [ { input: 'src/index.ts', // 替换为你的实际入口文件路径 output: [ { file: 'dist/cjs/index.js', format: 'cjs', sourcemap: true, }, { file: 'dist/esm/index.js', format: 'esm', sourcemap: true, }, ], plugins: [resolve(), commonjs(), typescript({ tsconfig: './tsconfig.json' })], external: ['react', 'react-dom'], // 标记React为外部依赖 }, { input: 'dist/esm/types/index.d.ts', // 匹配你的类型文件路径 output: [{ file: 'dist/index.d.ts', format: 'esm' }], plugins: [dts()], }, ];
- 重新打包组件包
执行打包命令重新生成产物:
npm run rollup
- 更新测试项目依赖
在测试项目中更新组件包版本,确保项目已安装正确版本的React,然后重新启动项目。
完成以上步骤后,组件包将复用测试项目中的React实例,Hook就能正常工作,组件也能正常渲染了。
内容的提问来源于stack exchange,提问作者henrie
相关产品推荐
相关产品推荐

