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

Vite构建React库在Next.js中报错:Cannot read properties of null (reading 'useRef')

问题:React组件库在Next.js中运行报错TypeError: Cannot read properties of null (reading 'useRef')

我用Vite构建了一个React组件库,配置及代码如下:

组件库代码与配置

src/components/index.js

import { useRef } from 'react'

export function Foo() {
  const ref = useRef()

  return <div ref={ref}>Hi!</div>
}

vite.config.js

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { resolve } from 'node:path'

export default defineConfig({
  plugins: [react()],
  build: {
    lib: {
      entry: resolve('src', 'components/index.js'),
      // other stuff
    },
    manifest: true,
    rollupOptions: {
      external: ['react', 'react-dom'],
      output: {
        globals: {
          react: 'React',
          'react-dom': 'ReactDOM',
        },
      },
    },
  }
})

package.json

{
  "name": "foo",
  "type": "module",
  "exports": {
    ".": {
      "import": "./dist/foo.es.js",
      "require": "./dist/foo.umd.js"
    }
  },
  "scripts": {
    "dev": "vite",
    "build": "rm -rf dist && vite build",
    "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
  },
  "devDependencies": {
    // some dev depencencies
  },
  "peerDependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  }
}

Next.js测试项目配置

package.json

{
  "name": "example-nextjs-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "foo": "link:../../foo",
    "next": "14.0.4",
    "react": "^18",
    "react-dom": "^18"
  },
  "devDependencies": {
     // some dev depencencies
  }
}

组件使用代码

import { Foo } from 'foo'

export function Header() {
  return <Foo />
}

操作流程:组件库目录执行pnpm install+pnpm run build,Next.js项目目录执行pnpm install+pnpm run dev,访问页面时触发运行时错误:TypeError: Cannot read properties of null (reading 'useRef')。


解决方案

这个错误的核心是React双实例冲突:组件库通过link方式引入时,加载了自身node_modules里的React,和Next.js项目的React实例重复,导致Hooks无法正常绑定到正确的React上下文。

方案1:修改组件库的peerDependencies配置

在组件库的package.json中添加peerDependenciesMeta,标记React和ReactDOM为可选,避免link时本地安装重复依赖:

{
  // ... 其他原有配置
  "peerDependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "peerDependenciesMeta": {
    "react": {
      "optional": true
    },
    "react-dom": {
      "optional": true
    }
  }
}

方案2:Next.js中强制使用项目自身的React

在Next.js项目根目录新建/修改next.config.js,添加webpack别名配置,强制组件库使用项目的React实例:

const path = require('path')

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      react: path.resolve('./node_modules/react'),
      'react-dom': path.resolve('./node_modules/react-dom'),
    }
    return config
  },
}

module.exports = nextConfig

方案3:用pnpm配置提升React依赖

在组件库目录新建.npmrc文件,添加以下配置,强制React相关依赖被提升到顶层node_modules,避免双实例:

public-hoist-pattern[]=react
public-hoist-pattern[]=react-dom

如果link模式的问题难以排查,可以直接打包组件库为本地包安装:

  1. 组件库目录执行:pnpm pack,生成foo-x.x.x.tgz文件
  2. 修改Next.js项目的package.json依赖:
    "dependencies": {
      "foo": "../foo/foo-x.x.x.tgz",
      // ... 其他依赖
    }
    
  3. 执行pnpm install重新安装依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 00:42:41