You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

发布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文件。

修复步骤

  1. 添加peerDependencies声明
    在package.json中添加peerDependencies,明确组件包依赖React但不自带,由使用该包的项目提供:
"peerDependencies": {
  "react": "^18.0.0",
  "@types/react": "^18.0.0"
}

确保react和@types/react仅保留在devDependencies中,不要移到dependencies。

  1. 配置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()],
  },
];
  1. 重新打包组件包
    执行打包命令重新生成产物:
npm run rollup
  1. 更新测试项目依赖
    在测试项目中更新组件包版本,确保项目已安装正确版本的React,然后重新启动项目。

完成以上步骤后,组件包将复用测试项目中的React实例,Hook就能正常工作,组件也能正常渲染了。

内容的提问来源于stack exchange,提问作者henrie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:32:56