Введение

Недавно компания React выпустила новую версию своей библиотеки: React версии 18. У меня есть несколько приложений, которые я поддерживаю уже некоторое время, когда мы загрузились с помощью Create-React-App. Я расскажу, как перейти на версию 18, и о проблемах, с которыми я столкнулся на этом пути.

Здесь вы можете найти список изменений для React 18.

У меня также есть небольшая запись для моих мыслей по этому поводу здесь.

Миграция Create-React-App на React версии 18

Фактический процесс миграции происходит довольно быстро. Установим необходимые зависимости:

yarn add react react-dom

Команда create-react-app также выпустила версию 5.0.1, чтобы помочь процессу миграции и сделать так, чтобы любые новые приложения поставлялись с ним из коробки:

npm install --save --save-exact [email protected] 
or 
yarn add --exact [email protected]

Если вы используете Typescript, не забудьте обновить типы не только для React, но и для различных сторонних библиотек. Многие обновили свои приложения.

yarn add @types/react @types/react-dom @types/node --dev

Обязательные изменения

Первое, что нам нужно сделать, это изменить способ рендеринга нашего корневого узла в React. Первыйблок кода — это то, как он выглядит изначально.

import ReactDOM from 'react-dom'; 
import App from './App'; 
ReactDOM.render( <App /> , document.getElementById('root') );

Теперь мы собираемся использовать только что добавленную функцию createRoot:

import { createRoot } from 'react-dom/client'; 
import App from './App'; 
const container = document.getElementById('root'); 
const root = createRoot(container); 
root.render(<App />);

Миграция Create-React-App на React версии 18: Typescript

Если вы не используете Typescript, вы можете пропустить эту часть.

Во-первых, давайте проверим, со сколькими ошибками нам приходится иметь дело. Это будет варьироваться от проекта к проекту в зависимости от того, сколько несовместимых сторонних библиотек у вас может быть, но все они будут разрешены аналогичным образом.

Выполните следующую команду:

Ой, нам нужно исправить 36 ошибок. К счастью, большинство из них одинаковы.

Я использую Semantic UI в этом проекте и было несколько ошибок с компонентом UI Radio. Например, у меня была функция setView, которая принимала параметры из реквизита onChange. По какой-то причине я потерял набор параметров e и data.

Parameter 'data' implicitly has an 'any' type. onChange={(e, data) => setView(data.value as number)}

Я нажимаю F12 (для пользователей Windows) или щелкаю правой кнопкой мыши и перехожу к определению типа. На опоре onChange, чтобы проверить, что он должен возвращать, и вручную установить типы для функции.

Обязательно импортируйте тип из библиотеки и установите типы внутри самой функции.

import type { CheckboxProps } from 'semantic-ui-react';

<Radio 
// other props 
onChange={(e: React.FormEvent<HTMLInputElement>, data: CheckboxProps) => { // whatever your function does } } 
/>

Миграция Create-React-App на React версии 18: Sentry

Я также использую библиотеку Sentry для отслеживания ошибок в моем проекте. Вот краткое описание того, как это работает. Для часового я получил несколько ошибок с компонентом ErrorBoundary. Это, вероятно, будет исправлено, но мы можем сделать это заранее до тех пор.

React версии 18 требует, чтобы дочерние элементы были явно объявлены в реквизитах, отсюда и ошибка:

error TS2769: No overload matches this call. Overload 1 of 2, '(props: ErrorBoundaryProps | Readonly<ErrorBoundaryProps>): ErrorBoundary', gave the following error.

К счастью, есть библиотека patch-package, которая позволяет нам это исправить. Давайте установим его.

yarn add patch-package --dev

Как и раньше, давайте проверим определения типов для ErrorBoundary, вступив в них. Нажмите F12 или щелкните правой кнопкой мыши и перейдите к определению типа.

Как и предполагалось, тип не имеет детской опоры. Давайте добавим его, установив его в React.ReactNode.

export declare type ErrorBoundaryProps = { 
children: React.ReactNode;
 //...rest of the type, just ignore it

Чтобы patch-package распознал это изменение, мы должны запустить следующую команду в нашем терминале:

npx patch-package @sentry/react

Это создаст файл в нашем проекте с указанием изменений, которые мы исправили в библиотеке.

diff --git a/node_modules/@sentry/react/types/errorboundary.d.ts b/node_modules/@sentry/react/types/errorboundary.d.ts index 4e1f326..779e0e7 100644 --- a/node_modules/@sentry/react/types/errorboundary.d.ts +++ b/node_modules/@sentry/react/types/errorboundary.d.ts @@ -9,6 +9,7 @@ export declare type FallbackRender = (errorData: { resetError(): void; }) => React.ReactElement; export declare type ErrorBoundaryProps = { + children: React.ReactNode; /** If a Sentry report dialog should be rendered on error */ showDialog?: boolean; /**

Последний шаг — добавить следующую строку в наши скрипты в файле package.json.

"scripts": {
 // ...other scripts 
"postinstall": "patch-package" 
}

Примечание

В качестве небольшого отступления, если есть какие-либо библиотеки, которые вы не хотите исправлять, а просто хотите пока игнорировать ошибки, пока сопровождающие их исправляют. (Или, как вариант, вы можете открыть PR, чтобы исправить это! 😬) Просто добавьте немного ts-ignore в файл прямо перед ошибкой:

Завершение

Create-React-App по-прежнему является наиболее широко используемым методом начальной загрузки приложений React, поэтому возможность его переноса очень важна для некоторых пользователей. 🚀

Больше контента на Relatable Code

Если вам это понравилось, не стесняйтесь связаться со мной в LinkedIn или Twitter.

Ознакомьтесь с моей дорожной картой бесплатного разработчика и еженедельными новостями технологической отрасли в моем рассылках.

Первоначально опубликовано на https://relatablecode.com 18 апреля 2022 г.