解决React中遇到的 “xxxx”不能用作 JSX 组件问题

发表于:2022-04-23 00:27:17·阅读:663

2022 年 3 月 29 日,React 18 正式版发布,带来很多新的能力,React 终于不再支持 IE(前端界的努力,让 IE 去死)。新的版本发布,React 的整体生态圈也会同步更新支持,也就导致 npm 包的依赖不可避免的产生一些混乱。记录下今天小伙伴抛出来的问题。

问题背景

最近公司新立了一些新项目,我就用项目中公共的脚手架模版进行了复制,但是我对其中很多包也同步做了升级,并将yarn.lock文件做了删除,重新更新了依赖(本来打算将react也升级到18,但是发现 craco 并没有明确支持 React 18, antd也还在对React 18做适配支持,所以也就停留在了 17)。

然后问题就来了:
image.png

image.png

“SplitPane”不能用作 JSX 组件。
  其实例类型 "SplitPane" 不是有效的 JSX 元素。
    在这些类型中,"render()" 返回的类型不兼容。
      不能将类型“React.ReactNode”分配给类型“import("/Users/tulies/data/test/my-app/node_modules/@testing-library/react/node_modules/@types/react/index").ReactNode”。
        不能将类型“{}”分配给类型“ReactNode”。ts(2786)
'SplitPane' cannot be used as a JSX component.
  Its instance type 'SplitPane' is not a valid JSX element.
    The types returned by 'render()' are incompatible between these types.
      Type 'React.ReactNode' is not assignable to type 'import("/Users/tulies/data/test/my-app/node_modules/@testing-library/react/node_modules/@types/react/index").ReactNode'.
        Type '{}' is not assignable to type 'ReactNode'.ts(2786)

react-split-paneantd 的一些组件都报 “xxxxx”不能用作 JSX 组件。

分析原因

先看下出问题之前的 package.jsondependenciesdevDependencies 配置:

  "dependencies": {
    "antd": "^4.19.5",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-split-pane": "^0.1.92",
    "typescript": "4.1.2",
    "web-vitals": "^2.1.4"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.1.1",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.4.1",
    "@types/node": "^16.11.27",
    "@types/react": "^17.0.44",
    "@types/react-dom": "^17.0.15"
  }

因为是删除了 yarn.lock 文件之后发生的问题,所以肯定是npm包的依赖出现了问题。脚手架中的几个核心包我都是一直同步最新的包更新,所以应该不是这些包的问题,所以想到会不会是 React 18 的问题。 虽然想到了这点了,但是起初也没到想到会是 @types/react-dom 的问题,经过很笨的的排除法终于找到这点。

@types/react-dom 的 package.json 中,dependencies 设置了@types/react 版本为 '*',但是现在最新版本已经是 18. 虽然在 package.json 中指定了 ^17.0.44,但是 @types/react-dom 还是会安装自己的依赖包。
image.png

解决办法

通过 resolutions 指定版本

"resolutions": {
  "@types/react": "17.0.44"
},

tips: 我用的是 yarn ,如果您使用的是npm 的话,您还需要在 package.json 的 script 中添加如下 preinstall,通过使用npm-force-resolutions包来根据 resolutions 进行版本限定。

"preinstall": "npm install --package-lock-only --ignore-scripts && npx npm-force-resolutions"
评论
文明评论,理性发言
⌘ + Enter
全部评论
暂无评论数据