升级到react@18和react-dom@18失败

Cra*_*han 14 typescript reactjs

我有一个现有的 React 17 应用程序,它最初是作为带有 TypeScript 选项的 create-react-app 输出。我想更改 package.json 以包含react@18.0.0然后react-dom@18.0.0启动应用程序,该步骤工作正常。

然后我尝试index.tsx按照 React 18 迁移说明告诉您的方式更改文件,将相关段更改为index.tsx

ReactDOM.createRoot(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud)

或者npm run build或者npm run start给我编译错误,说 createRoot 未定义。这可能是由于我依赖于@types/react@17.0.43@types/react-dom@17.0.14。对于 React 18,DefiniteTyped 似乎还没有这些文件的任何更新版本。

所以,我回去创建了一个全新的应用程序npx create-react-app react18 --template typescript。它现在需要react@18react-dom@18,但仍然具有旧的@types/依赖项。当您从 render() 切换到 createRoot() 时,它也会给出相同的编译错误。

作为进一步的一步,我问自己“如果我们忽略 TypeScript 会发生什么?” 使用 . 创建了另一个应用程序npx create-react-app react18js。它取决于react@18.0.0react-dom@18.0.0符合预期,但仍会ReactDOM.render()在其index.js输出中生成。

这可行,但是更改ReactDOM.renderReactDOM.createRoot并且您不会得到编译错误,但如果您尝试,您也不会得到可见的输出npm run start<App/>它似乎根本没有渲染该组件。

我错过了什么吗?这些说明还不够充分吗?

Yas*_* AZ 21

ReactDOM您需要首先从元素导入,然后使用react-dom/client 元素创建根元素,然后使用在创建的根元素内渲染组件的内容,如下所示:id=rootcreateRoot.render<App/>

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

let root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);

root.render(
  <React.StrictMode>
      <App />
  </React.StrictMode>,
);
Run Code Online (Sandbox Code Playgroud)


小智 11

React 文档解释了如何使用ReactDOM.createRoot,它不是ReactDOM.render.

该文档没有介绍使用它的 TypeScript 方式。

我知道这个解决方案与其他在 DOM 元素上使用类型断言 ( ) 的解决方案相比有点矫枉过正as HTMLElement,但它充分利用了严格类型的好处(例如,如果有人不小心删除了#rootindex.html 中的元素)

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'

const el = document.getElementById('root')
if (el === null) throw new Error('Root container missing in index.html')

const root = ReactDOM.createRoot(el)
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
)
Run Code Online (Sandbox Code Playgroud)


Moh*_*alo 5

因为您使用的是 typescript 您还需要升级 @types/react @types/react-dom 。

npm uninstall @types/react @types/react-dom


npm i -D @types/react @types/react-dom


Run Code Online (Sandbox Code Playgroud)

或者您可以直接更新到最新版本

然后更新你的index.js,如下所示:

import React from 'react';

import { createRoot } from 'react-dom/client';


const root = createRoot(document.getElementById('root') as HTMLDivElement);

root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

Run Code Online (Sandbox Code Playgroud)

如果需要,还可以考虑关闭并打开编辑器


小智 0

您必须使用 createRoot 定义根元素并渲染组件。

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
Run Code Online (Sandbox Code Playgroud)