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

升级至Next.js 12后React-Dom组件类型无效错误的排查求助

问题:Next.js 10 升级至 12 后出现 React 组件类型错误

升级大型项目到 Next.js 12 后,出现以下错误:

app_container  | Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
app_container  |     at renderElement (/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6043:9)
app_container  |     at renderNodeDestructiveImpl (/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6104:11)
app_container  |     at renderNodeDestructive (/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6076:14)
app_container  |     at renderForwardRef (/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5859:5)
app_container  |     at renderElement (/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6005:11)
app_container  |     at renderNodeDestructiveImpl (/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6104:11)
app_container  |     at renderNodeDestructive (/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6076:14)
app_container  |     at renderNode (/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6259:12)
app_container  |     at renderHostElement (/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5642:3)
app_container  |     at renderElement (/app/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5952:5)

无法准确定位错误位置,项目代码量大难以找到根源。已知这类错误常和导入时的对象解构有关,但不知道怎么定位具体位置。

附上 package.json 片段:

{
  ...
  "scripts": {
    "dev": "yarn && TSC_NONPOLLING_WATCHER=1 NODE_ENV=development nodemon",
    "generate": "graphql-codegen",
    "build": "next build && tsc --project tsconfig.server.json",
    "start": "NODE_ENV=production node dist/server.js",
    "build:preprod": "PORT=3332 next build && tsc --project tsconfig.server.json",
    "start:preprod": "PORT=3332 NODE_ENV=production node dist/server.js",
    "lint": "eslint --ext .tsx --ext .ts .",
    "clean": "npx rimraf node_modules && npx rimraf .next"
  },
  "dependencies": {
    "@apollo/client": "^3.7.15",
    "@apollo/react-common": "^3.1.4",
    "@apollo/react-components": "^4.0.0",
    "@apollo/react-hoc": "^4.0.0",
    "@apollo/react-hooks": "^4.0.0",
    "@codemirror/basic-setup": "^0.18.2",
    "@codemirror/commands": "^0.18.3",
    "@codemirror/gutter": "^0.18.4",
    "@codemirror/lang-javascript": "^0.18.0",
    "@codemirror/lang-markdown": "^0.18.4",
    "@codemirror/state": "^0.18.7",
    "@codemirror/theme-one-dark": "^0.18.1",
    "@codemirror/view": "^0.18.17",
    "@graphql-codegen/cli": "^2.2.0",
    "@graphql-codegen/introspection": "^2.1.1",
    "@graphql-codegen/typescript": "^2.2.2",
    "@graphql-codegen/typescript-operations": "^2.1.4",
    "@graphql-codegen/typescript-react-apollo": "^3.1.4",
    "@graphql-codegen/typescript-react-query": "^3.5.8",
    "@svgr/webpack": "^5.5.0",
    "@types/react": "^17.0.20",
    "add": "^2.0.6",
    "apollo-client": "^2.6.10",
    "babel-plugin-transform-define": "^2.0.1",
    "core-js": "^3.2.1",
    "eslint-config-prettier": "^8.3.0",
    "express": "^4.17.1",
    "graphql": "^15.0.0",
    "graphql-tag": "^2.10.1",
    "lang-papershive": "^0.1.16",
    "moment": "^2.29.4",
    "next": "12",
    "next-fonts": "^1.5.1",
    "next-plugin-custom-babel-config": "^1.0.5",
    "next-routes": "^1.4.2",
    "node-fetch": "^2.6.1",
    "pdfjs": "^2.4.7",
    "pdfjs-dist": "2.16.105",
    "react": "latest",
    "react-apollo": "^3.1.5",
    "react-csv": "^2.2.2",
    "react-device-detect": "^2.2.2",
    "react-dom": "latest",
    "react-fast-compare": "^3.2.0",
    "react-mathjax": "^1.0.1",
    "react-pdf": "^5.7.2",
    "react-player": "^2.9.0",
    "react-querybuilder": "^5.1.1",
    "react-sortable-hoc": "^2.0.0",
    "styled-components": "v6.0.0-rc.1",
    "vue": "3.0.5"
  },
  "devDependencies": {
    "@types/express": "^4.17.1",
    "@types/graphql": "^14.2.3",
    "@types/node": "^17.0.21",
    "eslint": "7.32.0",
    "eslint-config-next": "11 ",
    "nodemon": "^2.0.12",
    "prettier": "^2.4.0",
    "regenerator-runtime": "^0.13.3",
    "ts-loader": "^9.2.3",
    "ts-node": "^10.9.1",
    "typescript": "^4.7.4"
  },
  "proxy": "localhost:3001"
}

排查方案

一、先处理依赖版本冲突(从你的 package.json 看有明显问题)

  • React 版本不匹配:Next.js 12 要求 React 17 或 18,但你用了 latest,同时 @types/react 是 17.0.20,版本不一致会导致渲染异常。固定 React 版本为 17.x(和类型包匹配):
    yarn add react@17.0.2 react-dom@17.0.2
    yarn add @types/react-dom@17.0.20 --dev
    
  • Apollo 版本冲突:你同时安装了 @apollo/client@3.x 和旧版的 apollo-client@2.x、react-apollo@3.x,这些包会互相干扰。保留 @apollo/client@3.x,删除所有旧版 Apollo 相关包:
    yarn remove apollo-client react-apollo @apollo/react-common @apollo/react-components @apollo/react-hoc @apollo/react-hooks
    
    3.x 的 @apollo/client 已经包含了所有 hooks 和组件,不需要单独安装旧包。
  • styled-components 版本问题:你用了 v6.0.0-rc.1 候选版本,Next.js 12 对它的兼容性可能有问题,降级到稳定的 v5.x:
    yarn add styled-components@5.3.11
    
  • ESLint 配置不匹配:eslint-config-next 是 11,和 Next.js 12 版本不一致,升级到 12.x:
    yarn add eslint-config-next@12 --dev
    

二、定位具体错误组件

  • 开启 React 严格模式:在 _app.tsx 中启用严格模式,会放大渲染错误,帮助定位问题:
    import { StrictMode } from 'react';
    import type { AppProps } from 'next/app';
    
    function MyApp({ Component, pageProps }: AppProps) {
      return (
        <StrictMode>
          <Component {...pageProps} />
        </StrictMode>
      );
    }
    
    export default MyApp;
    
  • 逐步注释页面组件:先从首页开始,注释掉页面内的组件,逐个恢复,看哪个组件导致错误。如果是服务端渲染(SSR)的问题,可以先关闭页面的 SSR,用 dynamic 导入组件禁用 SSR:
    import dynamic from 'next/dynamic';
    
    const ProblemComponent = dynamic(() => import('../components/ProblemComponent'), {
      ssr: false,
    });
    
  • 检查导入方式:这类错误大多是默认导入/命名导入搞混,比如:
    • 错误:import { Button } from './Button' 但组件是默认导出 export default Button
    • 错误:import Button from './Button' 但组件是命名导出 export const Button = ...
      可以用 VS Code 全局搜索查找可疑导入,或者开启 TypeScript strict 模式,让编译错误提示导入不匹配的问题。
  • 临时修改 React-Dom 源码打印信息:在报错的 renderElement 函数里添加打印代码,输出当前要渲染的元素,找到那个类型为 object 的组件:
    打开 node_modules/react-dom/cjs/react-dom-server.browser.development.js,找到 renderElement 函数,在报错行前添加:
    console.log('Rendering element:', element);
    console.log('Element type:', typeof element.type);
    
    运行项目就能看到具体是哪个组件出问题。

三、清理缓存和重新构建

  1. 执行清理命令:
    yarn clean
    
  2. 删除 yarn.lock,重新安装依赖:
    rm yarn.lock && yarn install
    
  3. 重新构建项目:
    yarn build
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:17:01