基于tsup构建的React/TS库在Next.js中出现useState类型错误求助
React组件库在Next.js中出现useState/useEffect运行时错误的解决思路
核心原因
你的组件库构建时将React打包进了产物,导致Next.js项目中同时存在两个独立的React实例。React Hooks依赖于同一个实例内部的上下文状态,跨实例调用就会抛出Cannot read properties of null (reading 'useState')这类错误。而React.version能正常打印是因为它是静态全局属性,不依赖实例内部状态。
解决步骤
1. 配置tsup排除React依赖
在tsup.config.ts中添加external配置,将React和ReactDOM标记为外部依赖,让构建工具不把它们打包进组件库产物,而是直接使用宿主项目(Next.js)提供的React实例:
import { defineConfig } from 'tsup'; export default defineConfig({ entry: ['src/index.ts'], format: ['esm'], external: ['react', 'react-dom'], // 关键配置:排除React相关依赖 dts: true, clean: true, });
2. 声明Peer Dependencies
在组件库的package.json中明确声明React的peer依赖,强制宿主项目提供符合版本要求的React,避免版本不兼容或重复加载:
"peerDependencies": { "react": "^18.0.0", "react-dom": "^18.0.0" }, "peerDependenciesMeta": { "react": { "optional": false }, "react-dom": { "optional": false } }
3. 验证构建产物
重新构建组件库后,检查dist目录下的ESM文件,确认代码中仅存在import React from 'react'这类导入语句,没有包含React的内部实现代码(比如搜索useState,不应出现其具体逻辑)。
4. Next.js侧排查(可选)
如果问题仍存在,检查Next.js的next.config.js:
- 若使用了
transpilePackages,确保你的组件库被正确添加到列表中,让Next.js正确转译库的代码 - 确认没有自定义的模块解析规则导致React被重复加载
内容的提问来源于stack exchange,提问作者Manuel Bieh
相关产品推荐
相关产品推荐

