Эта статья — перевод основных изменений версии реакта 18.0.0 https://github.com/facebook/react/releases/tag/v18.0.0
Также я веду телеграм канал “Frontend по-флотски”, где рассказываю про интересные вещи из мира разработки интерфейсов.
Новые фичи
React
useId — это новый хук для создания уникальных идентификаторов как на клиенте, так и на сервере, избегая при этом hydration несоответствий. Это в первую очередь полезно для библиотек компонентов, интегрирующихся с API, для которых требуются уникальные идентификаторы. Это решает проблему, которая уже существует в React 17 и более ранних версиях, но еще более важна в React 18 из-за того, что новый рендерер сервера доставляет HTML не по порядку.
startTransition и useTransition позволяют помечать некоторые обновления состояния как несрочные. Другие обновления состояния по умолчанию считаются срочными. React позволит срочным обновлениям состояния (например, обновлению ввода текста) прерывать несрочные обновления состояния (например, отображение списка результатов поиска).
useDeferredValue позволяет отложить повторный рендеринг несрочной части дерева. Он похож на debouncing, но имеет несколько преимуществ по сравнению с ним. Фиксированной задержки по времени нет, поэтому React попытается выполнить отложенный рендеринг сразу после того, как первый рендер отобразится на экране. Отложенный рендеринг может быть прерван и не будет блокировать ввод данных пользователем.
useSyncExternalStore — это новый хук, который позволяет внешним хранилищам поддерживать параллельное чтение, заставляя обновления в хранилище быть синхронными. Он устраняет необходимость в useEffect при реализации подписок на внешние источники данных и рекомендуется для любой библиотеки, которая интегрируется со сторонним состоянием по отношению к React.
useInsertionEffect — это новый хук, который позволяет библиотекам CSS-in-JS решать проблемы с производительностью при внедрении стилей во время рендеринга. Если вы не планируете создавать библиотеку CSS-in-JS, мы не ожидаем, что вы когда-либо будете это использовать. Этот хук запустится после изменения DOM, но до того, как эффекты лейаута узнают об этом. Это решает проблему, которая уже существует в React 17 и более ранних версиях, но еще более важна в React 18, поскольку React уступает браузеру во время одновременного рендеринга, давая ему возможность пересчитать лейаут.
React DOM Client
Новое API теперь экспортируются из react-dom/client:
createRoot: новый метод создания корня для рендеринга или анмаунта. Используйте его вместо ReactDOM.render. Без него новые функции в React 18 не работают.
hydrateRoot: новый метод гидратации приложения, отображаемого на сервере. Используйте его вместо ReactDOM.hydra в сочетании с новыми API-интерфейсами React DOM Server. Без него новые функции в React 18 не работают.
И createRoot, и hydrateRoot принимают новый параметр onRecoverableError, на случай, если вы хотите получать уведомления, когда React восстанавливается после ошибок во время рендеринга или гидратации для ведения журнала. По умолчанию React будет использовать reportError или console.error в старых браузерах.
React DOM Server
Новый API теперь экспортируются из react-dom/server и имеет полную поддержку потоковой передачи Suspense на сервере:
renderToPipeableStream: для потоковой передачи в среде Node.
renderToReadableStream: для современных сред выполнения, таких как Deno и Cloudflare.
Существующий метод renderToString продолжает работать, но не рекомендуется его использовать.
Deprecations
react-dom: ReactDOM.render устарел. Его использование предупредит и запустит ваше приложение в режиме React 17.
react-dom: ReactDOM.hydrate устарел. Его использование предупредит и запустит ваше приложение в режиме React 17.
react-dom: ReactDOM.unmountComponentAtNode устарел.
react-dom: ReactDOM.renderSubtreeIntoContainer устарел.
react-dom/server: ReactDOMServer.renderToNodeStream устарел.
Критические изменения
React
Автоматическая пакетная обработка: в этом релизе представлено улучшение производительности, которое меняет способ пакетной обработки обновлений React для автоматического выполнения большей пакетной обработки. Дополнительную информацию см. в разделе Автоматическая пакетная обработка для меньшего количества рендеров в React 18. В редких случаях, когда вам нужно отказаться, оберните обновление состояния в flushSync.
Более строгий строгий режим: в будущем React предоставит функцию, позволяющую компонентам сохранять состояние между анмаунтами. Чтобы подготовиться к этому, React 18 вводит новую проверку только для разработки в строгом режиме. React автоматически анмаунтит и маунтит каждый компонент всякий раз, когда компонент создаётся в первый раз, восстанавливая предыдущее состояние при втором маунте. Если это сломает ваше приложение, рассмотрите возможность удаления строгого режима, пока вы не сможете исправить компоненты, чтобы они были устойчивы к повторному маунту с существующим состоянием.
Согласованное время useEffect: React теперь всегда синхронно сбрасывает функции эффектов, если обновление было запущено во время дискретного события пользовательского ввода, такого как щелчок или событие нажатия клавиши. Раньше поведение не всегда было предсказуемым или последовательным.
Более строгие ошибки гидратации: несоответствия гидратации из-за отсутствующего или дополнительного текстового содержимого теперь обрабатываются как ошибки, а не как предупреждения. React больше не будет пытаться «исправлять» отдельные узлы, вставляя или удаляя узел на клиенте в попытке сопоставить разметку сервера, и вернется к рендерингу клиента до ближайшей границы <Suspense> в дереве. Это гарантирует согласованность гидратированного дерева и позволяет избежать потенциальных дыр в конфиденциальности и безопасности, которые могут быть вызваны несоответствием гидратации.
Эффекты лейаута с задержкой: когда дерево повторно приостанавливается и возвращается к резервному варианту, React теперь очищает эффекты лейаута, а затем воссоздает их, когда содержимое внутри границы снова отображается. Это устраняет проблему, из-за которой библиотеки компонентов не могли правильно измерить лейаут при использовании с Suspense.
Новые требования к среде JS: React теперь зависит от современных функций браузеров, включая Promise, Symbol и Object.assign. Если вы поддерживаете более старые браузеры и устройства, такие как Internet Explorer, которые изначально не предоставляют современные функции браузера или имеют несовместимые реализации, рассмотрите возможность включения глобального полифилла в приложение.
Заметные изменения
React
Компоненты теперь могут отображать undefined: React больше не выбрасывает ошибку, если вы возвращаете undefined из компонента. Это делает допустимые возвращаемые значения компонентов согласованными со значениями, разрешенными в середине дерева компонентов. Мы предлагаем использовать линтер, чтобы предотвратить такие ошибки, как забывание оператора return перед JSX.
В тестах предупреждения об act теперь являются необязательными: если вы выполняете сквозные тесты, предупреждения об act не нужны. Мы ввели механизм отказа, поэтому вы можете включить их только для модульных тестов, где они полезны и выгодны.
Нет предупреждений о setState для несозданных компонентов: раньше React предупреждал об утечках памяти, когда вы вызывали setState для несозданного компонента. Это предупреждение было добавлено для подписок, но люди в основном сталкиваются с ним в сценариях, где состояние настроек в порядке, а обходные пути ухудшают код. Мы удалили это предупреждение.
Убрали скрытие журналов консоли: при использовании строгого режима React дважды визуализирует каждый компонент, чтобы помочь вам найти неожиданные побочные эффекты. В React 17 мы скрыли журналы консоли для одного из двух рендеров, чтобы облегчить чтение журналов. В ответ на отзывы сообщества о том, что это сбивает с толку, мы удалили скрытие. Вместо этого, если у вас установлен React DevTools, рендеры второго журнала будут отображаться серым цветом, и будет возможность (по умолчанию отключена) полностью их скрыть.
Улучшенное использование памяти: React теперь очищает больше внутренних полей при анмаунте, что делает влияние незафиксированных утечек памяти, которые могут существовать в коде вашего приложения, менее серьезным.
React DOM Server
renderToString: больше не будет возникать ошибка при приостановке на сервере. Вместо этого он выдаст резервный HTML-код для ближайшей границы <Suspense>, а затем повторит попытку рендеринга того же содержимого на клиенте. По-прежнему рекомендуется вместо этого переключиться на потоковый API, такой как renderToPipeableStream или renderToReadableStream.
renderToStaticMarkup: больше не будет возникать ошибка при приостановке на сервере. Вместо этого он выдаст резервный HTML-код для ближайшей границы <Suspense> и повторит попытку рендеринга на клиенте.