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

React组件库在CRA项目中使用useState时出现dispatcher is null错误求助

解决Vite构建React组件库在CRA项目中运行时dispatcher is null错误

问题背景

我用Vite+TypeScript开发了一个React组件库,其中TestComponent代码如下:

import React, { useState } from "react";

export const TestComponent = () => {
  console.log("CONTENT-TEST");
  const [yamlTemplate, setYamlTemplate] = useState<string>("test component");
  console.log("CONTENT", yamlTemplate);
  console.log("CONTENT-setTemplate", setYamlTemplate);

  return <div>Test Component</div>;
};

通过tsc && vite build构建组件库后,用npm install --save ../component-library将其安装到CRA创建的JavaScript React项目中。运行项目时出现以下错误:

dispatcher is null
useState@http://localhost:3000/static/js/bundle.js:2823:7
Qr@http://localhost:3000/static/js/bundle.js:46064:67
renderWithHooks@http://localhost:3000/static/js/bundle.js:22917:31

错误指向useState,但能看到CONTENT-TEST的日志输出。CRA项目中引入组件的代码:

import "./App.css";
import { TestComponent } from "component-library";

function App() {
  return (
    <div className="App">
      <TestComponent />
    </div>
  );
}

export default App;

组件库的Vite配置:

import { defineConfig } from "vite";
import dts from "vite-plugin-dts";
import { libInjectCss } from "vite-plugin-lib-inject-css";
import react from "@vitejs/plugin-react";
import path, { extname, relative, resolve } from "path";
import { fileURLToPath } from "node:url";
import { glob } from "glob";

export default defineConfig({
  build: {
    copyPublicDir: false,
    lib: {
      entry: resolve(__dirname, "src/index.tsx"),
      formats: ["cjs", "es"],         
    },
    rollupOptions: {
      external: ["react", "react-dom"], 
      input: Object.fromEntries(
        glob
          .sync("src/**/*.{ts,tsx}", {
            ignore: ["src/**/*.d.ts"],
          })
          .map((file) => [
            relative("src", file.slice(0, file.length - extname(file).length)),
            fileURLToPath(new URL(file, import.meta.url)),
          ]),
      ),
      output: {
        assetFileNames: "assets/[name][extname]",
        entryFileNames: "[name].js",
        globals: {
           react: 'React',
          'react-dom': 'ReactDOM',
         },
      },
    },
    sourcemap: true, 
    emptyOutDir: true, 
  },
  plugins: [react(), libInjectCss(), dts({ include: ["src"] })],    
});

组件库package.json的peerDependencies与CRA项目React版本一致:

"peerDependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },

问题原因

这个错误本质是React重复加载:组件库构建或安装过程中,出现了两份独立的React实例——CRA项目的React和组件库本地依赖的React,导致Hooks无法正确关联到React的dispatcher。

解决步骤

1. 确保组件库仅依赖宿主项目的React

检查组件库的package.json,将react和react-dom从dependencies中移除(如果之前误加),只保留在peerDependencies中,同时添加peerDependenciesMeta明确依赖要求:

"peerDependencies": {
  "react": "^18.3.1",
  "react-dom": "^18.3.1"
},
"peerDependenciesMeta": {
  "react": {
    "optional": false
  },
  "react-dom": {
    "optional": false
  }
}

2. 修正Vite构建配置,强化React外部化

调整Vite配置,确保React相关模块完全被外部化,并优化输出文件的识别性:

import { defineConfig } from "vite";
import dts from "vite-plugin-dts";
import { libInjectCss } from "vite-plugin-lib-inject-css";
import react from "@vitejs/plugin-react";
import path, { resolve } from "path";

export default defineConfig({
  build: {
    copyPublicDir: false,
    lib: {
      entry: resolve(__dirname, "src/index.tsx"),
      formats: ["cjs", "es"],
      fileName: (format) => `component-library.${format}.js`,
    },
    rollupOptions: {
      // 精确外部化React所有相关模块
      external: ["react", "react-dom", /^react\/.*/, /^react-dom\/.*/],
      output: {
        assetFileNames: "assets/[name][extname]",
        globals: {
          react: 'React',
          'react-dom': 'ReactDOM',
        },
      },
    },
    sourcemap: true,
    emptyOutDir: true,
  },
  plugins: [react(), libInjectCss(), dts({ include: ["src"] })],
});

同时在组件库package.json中明确指定入口文件:

"main": "./dist/component-library.cjs.js",
"module": "./dist/component-library.es.js",
"types": "./dist/index.d.ts",
"files": [
  "dist"
]

3. 清理重复依赖并重新安装

  • 卸载CRA项目中的组件库:npm uninstall component-library
  • 删除CRA项目的node_modules、package-lock.json(或yarn.lock)
  • 组件库重新构建:vite build(无需单独执行tsc,vite-plugin-dts已处理类型声明)
  • 重新安装组件库到CRA项目:npm install --save ../component-library
  • 在CRA项目根目录执行npm ls react,确认输出中只有一个React版本实例

4. 验证修复

启动CRA项目,检查TestComponent是否正常渲染,控制台是否不再出现dispatcher is null错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 17:55:03