Как обновиться до React 18
React 18 развивает популярную структуру компонентов JavaScript с новыми функциями, основанными на одновременном рендеринге и натяжении. Он обещает лучшую производительность, больше функций и улучшенный опыт разработчиков для приложений, которые переключаются.
В этой статье мы покажем вам, как обновить существующие кодовые базы до React 18. Обратите внимание, что это руководство представляет собой лишь обзор наиболее часто применимых изменений. Миграция должна быть довольно безболезненной для небольших проектов, которые уже следуют лучшим практикам React; большие наборы сложных компонентов могут вызвать некоторые проблемы, о которых мы расскажем ниже.
Реакция 18 . установить
Прежде чем делать что-либо еще, используйте npm для обновления зависимости React вашего проекта до версии 18:
$ npm install react@latest react-dom@latest
Новая версия технически не имеет обратной несовместимости. Новые функции активируются по подписке. Поскольку вы еще не меняли код, вы сможете запустить свое приложение и посмотреть, как оно правильно отображается. Ваш проект будет работать с существующим поведением React 17.
$ npm start
Включение функций React 18: новый корневой API
Использование React 18 без каких-либо изменений в кодовой базе имеет один побочный эффект: вы будете видеть предупреждение консоли браузера каждый раз, когда ваше приложение активируется в режиме разработки.
ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17.
Это сообщение об обесценивании можно смело игнорировать, если вы не готовы обновить свой проект. Чтобы использовать возможности React 18, вы должны внести изменения, описанные здесь. Старый ReactDOM.render() функция была заменена новым корневым API, который более объектно-ориентирован. Помимо повышения простоты использования, он также активирует систему одновременного отображения, которая позволяет использовать все новые функции заголовков.
внутри вашего index.js или же app.js файл, найдите строки, подобные этой:
import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.render(App />, container);
Это типичная точка входа для приложения React. Он создает экземпляр импортированного App компонент в качестве корневого элемента вашего приложения. Отображаемый контент депонируется как innerHTML элемента HTML с id=»react» .
Чтобы переключиться на корневой API React 18, замените приведенный выше код следующим:
import App from "./App.js"; import createRoot> from "react-dom/client"; const container = document.getElementById("react"); const root = createRoot(container); root.render(App />);
Это имеет эквивалентный эффект для старого ReactDOM.render() API. Вместо инициализации корневого элемента и рендеринга приложения в виде одной императивной операции React 18 позволяет сначала создать корневой объект, а затем явно отобразить содержимое.
Затем найдите в своем коде места, где вы отключаете корневой узел. Изменять ReactDOM.unmountComponentAtNode() к новому unmount() метод вашего корневого объекта:
// Before import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.render(App />, container); ReactDOM.unmountComponentAtNode(container); // After import App from "./App.js"; import createRoot> from "react-dom/client"; const container = document.getElementById("react"); const root = createRoot(container); root.render(App />); root.unmount();
Замените обратные вызовы рендеринга
ReactDOM.render() необязательный аргумент обратного вызова метода не имеет прямого аналога в корневом API React 18. Раньше вы могли использовать этот код для входа Rendered! в консоль после того, как React завершит рендеринг корневого узла:
import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.render(App />, container, () => console.log("Rendered!"));
Эта функция была удалена, поскольку время обратного вызова непредсказуемо при использовании новых функций частичной гидратации и потокового рендеринга сервера React 18. Если вы уже используете обратные вызовы рендеринга и вам необходимо поддерживать совместимость, вы можете добиться аналогичного поведения, используя механизм refs:
import createRoot> from "react-dom/client"; const App = (callback>) => ( div ref=callback>> h1>Demo Apph1> div> ); const container = document.getElementById("react"); const root = createRoot(container); root.render(App callback=() => console.log("Rendered!")> />);
React вызывает ссылки на функции при запуске компонентов. Установив ссылку на компонент, который является вашим корневым узлом, вы можете определить, когда происходит рендеринг, что дает эффект, аналогичный старой системе обратного вызова рендеринга.
Обнаружение проблем с обновлением
Теперь ваше приложение должно отображаться с функциями React 18 и без предупреждений консоли. Тщательно протестируйте свое приложение, чтобы убедиться, что все работает должным образом. Если у вас возникнут какие-либо проблемы, вы сможете исправить их с помощью этих распространенных решений.
Проверить
Приложения упакованы в Компонент может вести себя по-разному при рендеринге в режиме разработки React 18. Это связано с тем, что строгий режим теперь проверяет, поддерживает ли ваша кодовая база многократно используемое состояние, концепция, которая будет полностью представлена в React в будущем выпуске.
Состояние многократного использования позволяет React повторно связать ранее удаленный компонент, автоматически восстанавливая последнее состояние. Это требует, чтобы ваши компоненты могли выдерживать вызовы с двойным эффектом. Строгий режим теперь помогает вам подготовиться к повторному использованию, имитируя монтаж, демонтаж и повторную сборку ваших компонентов каждый раз, когда они используются, решая проблемы, когда предыдущее состояние не может быть восстановлено. Вы можете отключить строгий режим, если он обнаружит проблемы в вашем приложении или его зависимостях, которые вы не хотите исправлять.
Пакетная обработка состояния поддержки
React 18 изменяет способ пакетной обработки обновлений статуса для повышения производительности. Когда вы несколько раз меняете значения состояния в функции, React пытается объединить их в одном повторном рендеринге:
const Component = () => const [query, setQuery] = useState(""); const [queryCount, setQueryCount] = useState(0); /** * Two state updates, only one re-render */ setQuery("demo"); setQueryCount(queryCount + 1); >;
Этот механизм повышает эффективность, но раньше работал только в обработчиках событий React. В React 18 он работает со всеми обновлениями статуса, даже если они исходят от собственных обработчиков событий, тайм-аутов или промисов. Некоторый код может вести себя иначе, чем раньше, если вы выполняете последовательные обновления состояния в одном из этих мест.
const Component = () => const [query, setQuery] = useState(""); const [queryId, setQueryId] = useState(""); const [queryCount, setQueryCount] = useState(0); const handleSearch = query => fetch(query).then(() => setQuery("demo"); setQueryCount(1); // In React 17, sets to "query-1" // In React 18, sets to "query-0" - previous state update is batched with this one setQueryId(`query-$queryCount>`); >); > >;
Вы можете отключить это поведение в ситуациях, когда вы не готовы реорганизовать свой код. Перенести обновления статуса flushSync() чтобы заставить их совершить немедленно:
const Component = () => const [query, setQuery] = useState(""); const [queryId, setQueryId] = useState(""); const [queryCount, setQueryCount] = useState(0); const handleSearch = query => fetch(query).then(() => flushSync(() => setQuery("demo"); setQueryCount(1); >); // Sets to "query-1" setQueryId(`query-$queryCount>`); >); > >;
Прекратите использовать удаленные и неподдерживаемые функции
После того, как все вышеперечисленные аспекты будут учтены, ваше приложение должно быть полностью совместимо с React 18. Хотя все еще есть несколько изменений поверхности API, они не должны влиять на большинство приложений. Вот некоторые из них, на которые следует обратить внимание:
- unstable_changedBits устранен – Этот неподдерживаемый API позволял отказаться от обновлений контекста. Он больше не доступен.
- Object.assign() полифил был удален – Вы должны вручную ввести . добавить object-assign пакет polyfill, если вам нужно поддерживать очень старые браузеры без встроенного Object.assign() .
- Internet Explorer больше не поддерживается — React официально отказался от совместимости с Internet Explorer до того, как браузер прекратит поддержку в июне. Вам не следует обновляться до React 18, если вы все еще хотите, чтобы ваше приложение работало в IE.
- Использование приостановки с undefined откат теперь равен null – Ограничение напряжения при fallback= были ранее пропущены, что позволяет коду каскадироваться до следующей родительской границы в древовидной структуре. React 18 теперь учитывает компоненты приостановки без отката.
Вид со стороны сервера
Приложения, использующие рендеринг на стороне сервера, нуждаются в еще нескольких изменениях для работы с React 18.
В соответствии с новым корневым API вам необходимо заменить старый hydrate() функция в вашем коде на стороне клиента с новым hydrateRoot() предоставлено react-dom/client упаковка:
// Before import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.hydrate(App />, container); // After import App from "./App.js"; import createRoot> from "react-dom/client"; const container = document.getElementById("react"); const root = hydrateRoot(container, App />);
В коде на стороне сервера замените устаревшие вызовы API рендеринга их новыми аналогами. В большинстве случаев необходимо изменить renderToNodeStream() к новому renderToReadableStream() . Новые потоковые API открывают доступ к возможностям рендеринга потокового сервера React 18, где сервер может продолжать доставлять новый HTML в браузер после первого рендеринга вашего приложения.
Начните использовать функции React 18
Теперь, когда вы обновились, вы можете начать делать свое приложение более мощным, включив в него функции React 18. Использование параллелизма в React означает, что рендеринг компонентов может быть прерван, что открывает новые возможности и более отзывчивые пользовательские интерфейсы.
Некоторые из добавленных функций включают в себя основные обновления Suspense, способ приоритизации обновлений статуса с помощью Transitions и встроенный механизм регулирования повторного рендеринга, вызванного несрочными, но частыми обновлениями. Также есть несколько изменений и улучшений: можно вернуться undefined компонента render() метод, предупреждение о вызове setState() для несмонтированных компонентов было удалено, а несколько новых HTML-атрибутов, таких как imageSizes , imageSrcSet а также aria-description распознаются средством визуализации React DOM.
Обзор
React 18 стабилен и готов к использованию. В большинстве случаев процесс обновления должен быть быстрым и простым, требуя только обновления npm и перехода на новый корневой API. Тем не менее, вам все равно нужно протестировать все ваши компоненты: они могут вести себя по-разному в некоторых ситуациях, например, в строгом режиме или при применении автоматического пакетирования.
Этот новый выпуск указывает на будущее направление React как высокопроизводительной среды для всех видов веб-приложений. Он также расширяет возможности рендеринга на стороне сервера React, добавляя приостановку на сервере и возможность продолжать потоковую передачу контента вашим пользователям после первого рендеринга. Это дает разработчикам больше гибкости для распределения рендеринга как на клиенте, так и на сервере.
Версии React
Полная история версий React доступна на GitHub.
Документация к последним версиям может быть также найдена ниже.
Примечание
Данная документация предназначениа для React 18. Документация для React 17 находится по адресу https://17.reactjs.org.
18.2.0
18.1.0
18.0.0
17.0.2
17.0.1
17.0.0
16.14.0
16.13.1
16.13.0
16.12.0
16.11
16.10.2
16.10.1
16.10
16.9
16.8
16.7
16.6
16.5
16.4
16.3
16.2
16.1
16.0
15.6
Документация
Сообщество
Дополнительно
Copyright © 2023 Meta Platforms, Inc.
Обновление до новых версий
Upgrading to new versions из React Native предоставит вам доступ к большему количеству представлений APIs,, инструментам разработчика и другим преимуществам. Обновление требует небольших усилий, но мы стараемся сделать его простым для вас.
Expo projects
Обновление проекта Expo до новой версии React Native требует обновления версий пакетов react-native , react и expo в файле package.json . Expo предоставляет команду upgrade для обновления этих и любых других известных зависимостей. См. Upgrading Expo SDK Walkthrough для получения актуальной информации об обновлении вашего проекта.
React Собственные проекты
Поскольку типичные проекты React Native по существу состоят из проекта Android, проекта iOS и проекта JavaScript, обновление может быть довольно сложным. В настоящее время существует два способа обновления собственного проекта React: с помощью React Native CLI или вручную с помощью Upgrade Helper .
React Собственный CLI
React Native CLI поставляется с командой upgrade , которая обеспечивает одношаговую операцию по обновлению исходных файлов с минимальным количеством конфликтов. Внутри используется проект rn-diff-purge , чтобы выяснить, какие файлы необходимо создать, удалить или изменить.
1. Запустите команду upgrade .
Команда upgrade работает поверх Git, используя git apply с 3-сторонним слиянием, поэтому для этого необходимо использовать Git. Если вы не используете Git, но все же хотите использовать это решение, вы можете узнать, как это сделать, в разделе Troubleshooting .
Выполните следующую команду, чтобы начать процесс обновления до последней версии:
npx react-native upgrade
Вы можете указать собственную версию React, передав аргумент, например, чтобы выполнить обновление до 0.61.0-rc.0 :
npx react-native upgrade 0.61.0-rc.0
Проект обновляется с использованием git apply с 3-сторонним слиянием, может случиться так, что вам потребуется разрешить несколько конфликтов после его завершения.
2. Разрешите конфликты
Конфликтующие файлы включают разделители, которые очень четко показывают, откуда происходят изменения. Например:
13B07F951A680F5B00A75B9A /* Release */ = < isa = XCBuildConfiguration; buildSettings = < ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; "iPhone Developer"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/HockeySDK.embeddedframework", "$(PROJECT_DIR)/HockeySDK-iOS/HockeySDK.embeddedframework", ); ======= CURRENT_PROJECT_VERSION = 1; >>>>>>> theirs HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/../node_modules/react-native/React/**", "$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**", );
Вы можете думать о «наших» как о «вашей команде», а об «их» как о «родной команде разработчиков React».
Upgrade Helper
Upgrade Helper — это веб-инструмент, который поможет вам при обновлении ваших приложений, предоставляя полный набор изменений, происходящих между любыми двумя версиями. Он также показывает комментарии к определенным файлам, чтобы помочь понять, почему это изменение необходимо.
1. Выберите версии
Сначала вам нужно выбрать версию и до какой версии вы хотите обновиться, по умолчанию выбираются последние основные версии. После выбора вы можете нажать кнопку «Show мне, как обновить».
В основных обновлениях вверху будет отображаться раздел «Полезный контент» со ссылками, которые помогут вам при обновлении.
2. Обновите зависимости
Первый показанный файл — это package.json , хорошо бы обновить отображаемые там зависимости. Например, если react-native и react отображаются как изменения, вы можете установить их в свой проект, запустив yarn add :
# > и > — версии выпуска, показанные в diff yarn add react-native@> yarn add react@>
3. Обновите файлы проекта
Новый выпуск может содержать обновления для других файлов, которые создаются при запуске npx react-native init . Эти файлы перечислены после package.json на странице помощника по обновлению. Если нет других изменений, вам нужно только пересобрать проект, чтобы продолжить разработку.
Если есть изменения, вы можете обновить их вручную, скопировав и вставив изменения на странице, или вы можете сделать это с помощью команды обновления React Native CLI, выполнив:
npx react-native upgrade
Это проверит ваши файлы на соответствие последнему шаблону и выполнит следующие действия:
- Если в шаблоне есть новый файл, он создается.
- Если файл в шаблоне идентичен вашему файлу, он пропускается.
- Если файл в вашем проекте отличается от шаблона, вам будет предложено; у вас есть варианты сохранить файл или перезаписать его версией шаблона.
Некоторые обновления не будут выполняться автоматически с React Native CLI и требуют ручной работы, например, с 0.28 до 0.29 или с 0.56 до 0.57 . Обязательно проверяйте release notes при обновлении, чтобы вы могли определить любые ручные изменения, которые могут потребоваться для вашего конкретного проекта.
Troubleshooting
Я хочу обновить с помощью React Native CLI, но не использую Git
Хотя ваш проект не должен обрабатываться системой управления версиями Git — вы можете использовать Mercurial, SVN, или ничего — вам все равно потребуется install Git в вашей системе, чтобы использовать npx react-native upgrade . Git также должен быть доступен в PATH . Если ваш проект не использует Git, инициализируйте его и зафиксируйте:
git init # Инициализировать репозиторий Git git add . # Подготовить все текущие файлы git commit -m "Upgrade react-native" # Сохраняем текущие файлы в коммите
После завершения обновления вы можете удалить каталог .git .
Я внес все изменения, но мое приложение все еще использует старую версию.
Такие ошибки обычно связаны с кешированием, рекомендуется установить react-native-clean-project , чтобы очистить весь кеш вашего проекта, а затем вы можете запустить его снова.
Как мне обновить компонент React Native?
Дело в том, что при нажатии кнопки у меня из инпута берется текст и через пропс передается компоненту Weather, а он уже выводит мне погоду. Но почему-то он делает это лишь один раз, либо нужно обновить приложение. Все данные доставляет, но почему-то он использует старые данные, хоть и должен новые. Как мне заставить компонент обновляться после каждого нажатия кнопки? APP.JS
function _onPressButton() < if (city!=null) return else return Waiting.. > const App: () => Node = () => < // this.state = < // city:'London' // >const [text, onChangeText] = React.useState(); const [text2, newtext] = React.useState(); return ( >> onChangeText= placeholder="Введите город" value= /> newtext(text)> /> /> ); >;
import Service from "../service/fetch"; function getWeather(city)< const [weatherList, renderWeather] = useState([]); useEffect(()=>< Service.API(city).then((json)=>< console.log(json); renderWeather([json]) console.log(weatherList); >); >,[]) console.log("УСТАНОВЛЕННЫЙ ГОРОД - "+city) city=null; return weatherList > const Weather=()=>() Weather.defaultProps= ( style=>> ))>