Депрекация
Давай начнем с деприкациях, устаревших частях кода, которые были включены в React v16.9; они помогут нам лучше подготовиться к v17 (и другим будущим версиям) в будущем.
Нет больше JavaScript: URL
URL-адреса, начинающиеся с javascript:
долгое время считались опасными из-за потенциальной возможности попадания вредоносных данных в приложение:
const userProfile = {
websiteUrl: "javascript: alert('you got hacked')";
}
<a href={userProfile.websiteUrl}>Мой веб-сайт</a>
Очевидно, было бы не очень хорошо, если б пользователи могли внедрить JavaScript прямо в работающее приложение.
Как уже упоминалось, этот функционал устарел в v16.9 и показывает только предупреждение. Можно использовать dangerouslySetInnerHTML
, но всё равно могут возникнуть проблемы.
В будущей основной версии (не обязательно v17) этот функционал будет вызывать ошибку. Лучше всего прекратить его использовать совсем, чтобы избежать неприятностей в будущем.
factory компонентов больше нет
Это довольно неясный шаблон кода, который был представлен командой React до того, как стали популярными компиляции классов с Babel. Он также имеет довольно неприятный синтаксис, который очень похож на функциональный компонент, - который возвращает объект с методом рендеринга:
function FactoryComponent() {
return {
render() {
return <div />;
}
};
}
Синтаксис выглядит довольно плохо, и, поскольку Babel стал стандартным компилятором для приложений React, этот шаблон компонента больше не нужен. Его поддержка приводит к тому, что React становится немного больше и медленнее, чем необходимо. В будущем выпуске он будет полностью удален.
React команда упомянула, что factory
компонент используется редко и, вероятно, не повлияет на большинство современных кодовых баз.
Если попытаешься использовать его, то получишь предупреждение. Есть и обходной путь, но, лучше преобразовать factory
в функциональный или классовый компонент.
Небезопасные методы жизненного цикла переименованы
Более года назад команда разработчиков подумала, что методы жизненного цикла, которые считались небезопасными, будут переименованы в будущем выпуске 16.x, а старые имена полностью удалены в версии 17.x.
Например:
componentWillMount
переименован вUNSAFE_componentWillMount
;componentWillReceiveProps
переименован вUNSAFE_componentWillReceiveProps
;componentWillUpdate
переименован вUNSAFE_componentWillUpdate
;
Переживать не стоит, старые имена будут по-прежнему работать в React v16.9, но выдавая полезное предупреждение, призывающее провести рефакторинг кода или перейти к новому UNSAFE_
наименованию.
Цель UNSAFE_
наименования состоит в том, чтобы облегчить нам, разработчикам, идентификацию потенциально проблемного кода при выполнении проверок и тому подобного.
Чтобы упростить миграцию, существует сценарий «codemod», который может обновить весь проект до нового соглашения об именах UNSAFE_
:
npx react-codemod rename-unsafe-lifecycles
Новый функционал
Этот выпуск React немного освещает новые функции.
Измерение производительности с <React.Profiler>
React Profiler
был впервые добавлен в React DevTools
в версии 16.5. Эта функция измеряет каждый отрисованный компонент, тем самым определяет «затраты» рендеринга и уязвимые места производительности в приложении React.
Чтобы использовать его, можем открыть DevTools в React, запустить запись, визуализировать некоторые компоненты React, а затем остановить запись.
Profiler
полезный, но немного громоздкий. Нужно начать запись и остановить её, а затем проверить части записи, которые имеют большое время загрузки. Вот почему у нас теперь есть компонент <React.Profiler>
, который можно использовать для сбора метрик производительности программным способом.
Для нового компонента требуется свойство id
, а также свойство onRender
, которое будет запускаться каждый раз при обновлении компонента в дереве и запускать повторную визуализацию:
import React, { Profiler } from "react";
render(
<Profiler id="my-app" onRender={onRender}>
<App>
<Switch>
<Route {...props} />
<Route {...props} />
</Switch>
</App>
</Profiler>
);
Обратный вызов onRender
будет получать информацию о том, какой компонент был повторно обработан, сколько времени это заняло и другую ценную информацию. Более подробно о profiler
здесь.
Кроме того, profiler автоматически отключается в production среде, поэтому нет никакой дополнительной логики для реализации его отключения.
Асинхронный ReactTestUtils.act()
В React v16.8 появилась утилита act()
, которая помогает разработчикам создавать тесты пользовательского интерфейса. При написании тестов пользовательского интерфейса существуют такие задачи как рендеринг, события взаимодействия с пользователем такие как щелчок или выборка данных, которые можно считать «единицами» взаимодействия с приложением React.
Из-за асинхронной природы JavaScript, React может на самом деле пропустить какую-то задачу и сразу же подтвердить тест, не дожидаясь его завершения.
React предоставляет вспомогательный метод act()
, который гарантирует, что все обновления, связанные с этими «модулями», были обработаны и применены к DOM прежде, чем он сделает какие-либо утверждения.
Хоть утилита act()
и была чрезвычайно полезной, она была синхронной, и не было простого способа заставить её работать более асинхронно. Это могло привести к некоторым единичным предупреждениям в логах.
К счастью, команда React улучшила утилиту act()
в React v16.9, чтобы та могла работать асинхронно!
await act(async () => {
// ...
});
Исправление ошибок
Релиз React никогда не завершается без каких-либо заметных исправлений ошибок:
-
Исправлена утечка памяти, вызванная сохранением удаленных поддеревьев;
-
Улучшение обработки бесконечных циклов, вызванных
setState
внутриuseEffect
.
Бесконечный цикл, вызванный setState
в useEffect
, теперь выводит аналогичную ошибку, которую видим, когда вызываем setState
в componentDidUpdate
в компоненте класса. Вот пример кода:
function App() {
const [counter, setCounter] = React.useState(0);
React.useEffect(() => {
setCounter(counter + 1);
});
return <h1>Watch out infinite loop in the console!</h1>;
}
- Исправлен сбой в
<Suspense>
при вызовеfindDOMNode()
.
Компонент <React.Suspense>
используется для отложенной загрузки компонентов, которые не нужны при первоначальной визуализации. Но, начиная с версии 16.7, многие разработчики начали получать сообщения об ошибке Invariant Violation: Unable to find node on an unmounted component
.
После проверки, разработчики выяснили, что ошибка вызвана вызовом ReactDOM.findDOMNode()
внутри Suspense
. В этом выпуске сбой исправлен.
Установка React v16.9
React v16.9 готов для установки; всё что нужно сделать - это установить его через любимый менеджер пакетов:
# Через npm
npm install --save react@^16.9.0 react-dom@^16.9.0
# Через yarn
yarn add react@^16.9.0 react-dom@^16.9.0
Источники
https://reactjs.org/blog/2019/08/08/react-v16.9.0.html
https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html