react strictmode что это
Strict Mode
Strict mode checks are run in development mode only; they do not impact the production build.
You can enable strict mode for any part of your application. For example:
StrictMode currently helps with:
Additional functionality will be added with future releases of React.
Identifying unsafe lifecycles
As explained in this blog post, certain legacy lifecycle methods are unsafe for use in async React applications. However, if your application uses third party libraries, it can be difficult to ensure that these lifecycles aren’t being used. Fortunately, strict mode can help with this!
When strict mode is enabled, React compiles a list of all class components using the unsafe lifecycles, and logs a warning message with information about these components, like so:
Addressing the issues identified by strict mode now will make it easier for you to take advantage of concurrent rendering in future releases of React.
Warning about legacy string ref API usage
Previously, React provided two ways for managing refs: the legacy string ref API and the callback API. Although the string ref API was the more convenient of the two, it had several downsides and so our official recommendation was to use the callback form instead.
React 16.3 added a third option that offers the convenience of a string ref without any of the downsides:
Since object refs were largely added as a replacement for string refs, strict mode now warns about usage of string refs.
Callback refs will continue to be supported in addition to the new createRef API.
You don’t need to replace callback refs in your components. They are slightly more flexible, so they will remain as an advanced feature.
Warning about deprecated findDOMNode usage
React used to support findDOMNode to search the tree for a DOM node given a class instance. Normally you don’t need this because you can attach a ref directly to a DOM node.
findDOMNode can also be used on class components but this was breaking abstraction levels by allowing a parent to demand that certain children were rendered. It creates a refactoring hazard where you can’t change the implementation details of a component because a parent might be reaching into its DOM node. findDOMNode only returns the first child, but with the use of Fragments, it is possible for a component to render multiple DOM nodes. findDOMNode is a one time read API. It only gave you an answer when you asked for it. If a child component renders a different node, there is no way to handle this change. Therefore findDOMNode only worked if components always return a single DOM node that never changes.
You can instead make this explicit by passing a ref to your custom component and pass that along to the DOM using ref forwarding.
You can also add a wrapper DOM node in your component and attach a ref directly to it.
In CSS, the display: contents attribute can be used if you don’t want the node to be part of the layout.
Detecting unexpected side effects
Conceptually, React does work in two phases:
The commit phase is usually very fast, but rendering can be slow. For this reason, the upcoming concurrent mode (which is not enabled by default yet) breaks the rendering work into pieces, pausing and resuming the work to avoid blocking the browser. This means that React may invoke render phase lifecycles more than once before committing, or it may invoke them without committing at all (because of an error or a higher priority interruption).
Render phase lifecycles include the following class component methods:
Because the above methods might be called more than once, it’s important that they do not contain side-effects. Ignoring this rule can lead to a variety of problems, including memory leaks and invalid application state. Unfortunately, it can be difficult to detect these problems as they can often be non-deterministic.
Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:
This only applies to development mode. Lifecycles will not be double-invoked in production mode.
For example, consider the following code:
At first glance, this code might not seem problematic. But if SharedApplicationState.recordEvent is not idempotent, then instantiating this component multiple times could lead to invalid application state. This sort of subtle bug might not manifest during development, or it might do so inconsistently and so be overlooked.
By intentionally double-invoking methods like the component constructor, strict mode makes patterns like this easier to spot.
Starting with React 17, React automatically modifies the console methods like console.log() to silence the logs in the second call to lifecycle functions. However, it may cause undesired behavior in certain cases where a workaround can be used.
Detecting legacy context API
The legacy context API is error-prone, and will be removed in a future major version. It still works for all 16.x releases but will show this warning message in strict mode:
Read the new context API documentation to help migrate to the new version.
3.18 Строгий режим
Проверки строгого режима работают только в режиме разработки; они не влияют на production билд.
Вы можете включить строгий режим для любой части вашего приложения. Например:
На данный момент StrictMode помогает с:
Дополнительные функциональные возможности будут добавлены в будущих релизах React.
3.18.1 Обнаружение компонентов, имеющих небезопасные методы жизненного цикла
Некоторые устаревшие методы жизненного цикла небезопасны для использования в асинхронных React-приложениях. Однако, если ваше приложение использует сторонние библиотеки, может оказаться сложным обеспечить, чтобы эти методы не использовались. К счастью, строгий режим может помочь с этим!
Когда строгий режим включен, React компилирует список всех компонентов-классов, использующих небезопасные методы жизненного цикла, и отображает предупреждающее сообщение с информацией об этих компонентах, например:
Теперь, решение проблем, выявленных в строгом режиме, облегчит использование вами всех преимуществ асинхронной отрисовки в будущих версиях React.
3.18.2 Предупреждение об использовании устаревшего строкового API для ref
Ранее React предоставлял два способа управления ссылками ref : устаревший строковый API и API обратного вызова. Хотя строковый API был более удобным, он имел ряд недостатков, поэтому наша официальная рекомендация заключалась в том, чтобы вместо него использовать форму обратного вызова.
React 16.3 добавил третий вариант, который предлагает удобство строки ref без каких-либо недостатков:
Вам не нужно заменять обратные вызовы в ваших компонентах. Они немного более гибкие, поэтому останутся в качестве продвинутой функции.
3.18.3 Предупреждением об использовании устаревшего метода findDOMNode
Ранее React использовал метод findDOMNode для поиска узла DOM по заданному экземпляру класса. Обычно вам это не нужно, так как вы можете прикрепить ссылку непосредственно к узлу DOM.
Вместо этого можно использовать передачу ссылок.
Вы также можете добавить обёртку дла DOM-узла в свой компонент и прикрепить ссылку непосредственно к ней.
3.18.3 Обнаружение неожиданных сторонних эффектов
Концептуально, React работает в две фазы:
К методам жизненного цикла фазы отрисовки относятся следующие методы компонента-класса:
Поскольку вышеупомянутые методы могут быть вызваны более одного раза, важно, чтобы они не содержали каких-либо сторонних эффектов. Игнорирование этого правила может привести к множеству проблем, включая утечку памяти и нерелевантное состояние приложения. К сожалению, бывает довольно трудно обнаружить эти проблемы, поскольку они часто могут быть недетерминированными.
Строгий режим не может автоматически обнаруживать для вас побочные эффекты, но он может помочь вам определить их, сделав их немного более детерминированными. Это достигается путем преднамеренного двойного вызова следующих методов:
Это применимо только к development режиму. Методы жизненного цикла не будут вызываться дважды в production режиме.
К примеру, рассмотрим следующий код:
На первый взгляд данный код может не показаться проблемным. Но если метод SharedApplicationState.recordEvent не является идемпотентным, то создание экземпляра этого компонента несколько раз может привести к недопустимому состоянию приложения. Такая тонкая ошибка может не проявляться во время разработки, или же она может возникать очень непоследовательно, и поэтому может быть упущена из виду.
Умышленно производя двойные вызовы методов, таких как конструктор компонента, строгий режим делает такие проблемные шаблоны более легкими для обнаружения.
3.18.5 Обнаружением устаревшего API контекста
Устаревший API контекста подвержен ошибкам и будет удален в будущей major версии. Он все еще работает для всех релизов 16.x, но в строгом режиме будет показано это предупреждение:
Изучите новую документацию по API контекста в данном разделе.
Новшества React 16.3(.0-alpha)
Новое API Context
API Context всегда выглядело как нечто таинственное. С одной стороны — это официальное, документированное API React, но, с другой стороны, разработчиков предупреждали о том, что использовать его не следует, так как оно может со временем измениться, и документация по нему, намеренно, была неполной. Теперь время этого API настало, фаза RFC пройдена, и новое API, которое, определённо, стало более дружелюбным, доступно разработчикам. Оно может облегчить вам жизнь, если всё, что вам нужно — простое управление состоянием без «излишеств» Redux или MobX.
Создание нового контекста командой React.createContext
Provider — это особый компонент, цель существования которого заключается в том, чтобы предоставлять данные всем компонентам в собственном поддереве. Например, это может выглядеть так:
Использование нового API Context — Context.Provider
Следующий шаг заключается в использовании элемента Consumer :
Использование нового API Context — Context.Consumer
Новые методы жизненного цикла
Ещё одно новшество, которое, из стадии RFC, перешло в рассматриваемый альфа-релиз React, касается признания устаревшими некоторых методов жизненного цикла и введения нескольких новых методов.
Это изменение нацелено на внедрение рекомендованных подходов к разработке (вот материал о том, почему с этими функциями может быть непросто обращаться), что обретёт особую важность после того, как будет полностью активирован асинхронный режим рендеринга (что является одной из важнейших целей архитектуры Fiber, появившейся в React 16).
Вот функции, которые через некоторое время признают устаревшими:
There will be NO breaking changes in React 16.3.0 (or anywhere in the 16.x release cycle). React respects semver (and always has). Don’t panic
Паника в стане React-разработчиков. Дэн Абрамов предлагает не беспокоиться, но его слова действуют не на всех
Статический метод getDerivedStateFromProps
Так как componentWillReceiveProps собираются убрать, нужны какие-то механизмы для обновления состояния на основании изменения свойств. Для решения этой задачи было решено представить новый статический метод.
Что такое статический метод? Это — метод, который существует в классе, а не в его экземплярах. Пожалуй, легче всего описать этот метод, как такой, у которого нет доступа к this и имеется ключевое слово static в его объявлении.
Использование getDerivedStateFromProps для обновления состояния
Возвращённое значение ведёт себя точно так же, как текущее значение setState — нужно лишь вернуть изменённую часть состояния, все остальные значения останутся такими же, как были.
Полезные советы по использованию getDerivedStateFromProps
▍Не забудьте инициализировать состояние
Помните о необходимости инициализации состояния
Инициализацию исходного состояния компонента никто не отменял. Делать это надо либо в конструкторе, либо путём настройки поля класса.
▍Особенности вызова getDerivedStateFromProps
Рассматриваемая функция вызывается и при первоначальном монтировании, и при перерисовке компонента, поэтому вы можете использовать её вместо создания в конструкторе состояния, основанного на свойствах.
▍Ошибка при совместном использовании getDerivedStateFromProps и componentWillReceiveProps
Предупреждение, в котором рекомендуется использовать только getDerivedStateFromProps
▍О коллбэках и componentDidUpdate
▍О ключевом слове static
Объявление getDerivedStateFromProps без использования ключевого слова static
Новый компонент StrictMode
Использование use strict… Ох, не то. Мы, конечно, имеем в виду компонент StrictMode
Смысл использования StrictMode заключается в том, что благодаря наличию этого компонента система помогает обеспечивать соответствие кода рекомендованным подходам к разработке.
Ошибка, сообщающая об использовании небезопасных методов жизненного цикла в поддереве StrictMode
Сейчас сообщение об ошибке указывает на RFC, где говорится об удалении методов жизненного цикла.
Новый компонент AsyncMode
Если вы хотите узнать подробности об асинхронных компонентах React, загляните сюда и сюда.
Новая версия инструментов разработчика React
В дополнение к вышеописанным новшествам, в релизе React, о котором мы говорим, была представлена новая версия инструментов разработчика, которая поддерживает отладку новых компонентов.
Если вы используете Chrome, то вам понадобится немного подождать, так как соответствующее расширение в Интернет-магазине Chrome пока не обновлено, а попытки отлаживать старыми инструментами новый код приводят к… интересным результатам:
Рекорд React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED пока ещё не побит
А вот пользователи Firefox уже могут отлаживать новые конструкции:
Новый асинхронный компонент можно видеть при отладке в Firefox
Итоги: самое интересное впереди
Тут мы рассмотрели новшества альфа-релиза React 16.3, однако, стабильная версия этого релиза может содержать в себе другой набор изменений. Если ориентироваться на слова Дэна Абрамова по этому поводу, то React 16.3.0 должен выйти совсем скоро.
На прошлой неделе говорили о следующей неделе, которая уже наступила
Уважаемые читатели! Что вы думаете о новых возможностях React?
Вышел React v.16.3.0
Несколько дней назад, мы написали пост о приближающихся изменениях в наших lifecycle-методах, где также затронули стратегию постепенной миграции (обновления). В React 16.3.0 мы добавили несколько новых lifecycle-методов для помощи в этой миграции. Мы также предоставили новое API для давно ожидаемых новшеств: официальное context API, ref forwarding API и ergonomic ref API.
Официальное Context API
Много лет React предлагал экспериментальное API для работы с контекстом. Пусть это и была мощная «штука», использование такого API было под угрозой, так как мы всё хотели заменить «экспериментальное» API.
Версия 16.3 представляет новое context API, которое эффективнее и поддерживает сразу как проверку статичных типов (static type checking) так и глубокие обновления (deep updates).
Старое context API будет работать для всех релизов 16й версии, поэтому у вас есть время мигрировать.
Ниже пример, в котором показано как можно «прокинуть» тему оформления (theme), используя новое API:
createRef API
React предоставлял два способа управления refs: указание ref обычной строкой и callback-вызов. Хотя и указание ref просто в качестве строки было удобнее, это имело несколько минусов и поэтому мы рекомендовали использовать вариант с callback’ом.
Версия 16.3 добавляет новую опцию для управления refs, которая предлагает удобство указания ref в виде строки без недочетов:
Callback refs будут поддерживаться и далее в новом createRef API. Не спешите заменять callback refs в ваших компонентах. Они более гибкие, поэтому мы оставим их для будущего продвинутого использования.
forwardRef API
Компоненты высшего порядка (или HOC) — удобный инструмент для «переиспользования» кода между компонентами. Если взять за основу предыдущий пример с context, мы можем создать HOC в который «прокинем» theme в качестве свойства (props):
Мы можем использовать этот HOC, чтобы связывать компоненты со свойствами темы оформления (theme) из контекста (context) без использования ThemeContext напрямую. Для примера:
Обычно HOC’и прокидывают свойства (props) в компонент, который они оборачивают. К сожалению, refs не прокидываются. Это значит, что мы не можем прикрепить ref к FancyButton когда используем FancyThemedButton. Выходит, вызвать focus() невозможно.
forwardRef API решает эту проблему, предлагая перехватить ref и послать его дальше как обычное свойство.
Изменения в методах жизненного цикла (lifecycle methods)
API создания компонентов с помощью class практически не изменялось несколько лет. Однако, мы добавили поддержку новых «фич» (таких как error boundaries или будущий async rendering mode) к которым данная модель была не готова как следует.
Например, с текущим API очень просто заблокировать начальную отрисовку компонента (initial render) несущественной логикой. Отчасти, это связано с тем, что существует несколько вариантов для решения поставленных задач, и поэтому выбрать лучший не просто. Мы заметили, что обработке ошибок часто не уделяется внимание и это может приводить к утечкам памяти (что в свою очередь пагубно скажется в будущем на асинхронной отрисовке (async rendering mode)). Текущее class API так же осложняет другие наши задумки, например работу над прототпированием React компилятора.
Большинство из таких проблем связано со следующими lifecycle-методами: componentWillMount, componentWillReceiveProps и ComponentWillUpdate. Так же эти методы вносят наибольшую путаницу в React коммьюнити. Поэтому, мы собираемся отказаться них в пользу лучшей альтернативы.
Конечно, мы понимаем, что такие изменения затронут огромное количество существующих компонентов. Поэтому миграция будет постепенной настолько, насколько это возможно. Мы также предложим пути отступления (У нас в Facebook — 50,000 компонентов. Мы так же нуждаемся в постепенном обновлении).
Deprecation (устаревший метод) предупреждение будет включено в будущих 16.x релизах, но поддержка текущих «жизненных циклов» будет работать до версии 17. Так же, в семнадцатой версии вы сможете использовать их с префиксом UNSAFE_. Мы приготовили автоматический скрипт для переименования.
В дополнении к будущим «deprecated» методам жизненного цикла, мы добавили парочку новых:
StrictMode компонент
StrictMode — это инструмент для нахождения потенциальных проблем в вашем приложении. Как и Fragment, StrictMode визуально не отрисовывается. Этот компонент активирует дополнительные проверки и предупреждения.
StrictMode работает только в development режиме (в режиме разработки, не в «проде»)
Несмотря на то, что невозможно поймать все проблемные места (например, некоторые типы мутаций), StrictMode компонент поможет во многих ситуациях. Если вы видите предупреждения в «строгом режиме» (strict mode), значит скорее всего у вас будут баги в асинхронном режиме отрисовки (async rendering mode).
В версии 16.3, StrictMode умеет:
Дополнительный функционал будет добавлен в будущих релизах React.
Strict Mode
Strict mode checks are run in development mode only; they do not impact the production build.
You can enable strict mode for any part of your application. For example:
StrictMode currently helps with:
Additional functionality will be added with future releases of React.
Identifying unsafe lifecycles
As explained in this blog post, certain legacy lifecycle methods are unsafe for use in async React applications. However, if your application uses third party libraries, it can be difficult to ensure that these lifecycles aren’t being used. Fortunately, strict mode can help with this!
When strict mode is enabled, React compiles a list of all class components using the unsafe lifecycles, and logs a warning message with information about these components, like so:
Addressing the issues identified by strict mode now will make it easier for you to take advantage of async rendering in future releases of React.
Warning about legacy string ref API usage
Previously, React provided two ways for managing refs: the legacy string ref API and the callback API. Although the string ref API was the more convenient of the two, it had several downsides and so our official recommendation was to use the callback form instead.
React 16.3 added a third option that offers the convenience of a string ref without any of the downsides:
Since object refs were largely added as a replacement for string refs, strict mode now warns about usage of string refs.
Callback refs will continue to be supported in addition to the new createRef API.
You don’t need to replace callback refs in your components. They are slightly more flexible, so they will remain as an advanced feature.
Warning about deprecated findDOMNode usage
React used to support findDOMNode to search the tree for a DOM node given a class instance. Normally you don’t need this because you can attach a ref directly to a DOM node.
findDOMNode can also be used on class components but this was breaking abstraction levels by allowing a parent to demand that certain children was rendered. It creates a refactoring hazard where you can’t change the implementation details of a component because a parent might be reaching into its DOM node. findDOMNode only returns the first child, but with the use of Fragments, it is possible for a component to render multiple DOM nodes. findDOMNode is a one time read API. It only gave you an answer when you asked for it. If a child component renders a different node, there is no way to handle this change. Therefore findDOMNode only worked if components always return a single DOM node that never changes.
You can instead make this explicit by passing a ref to your custom component and pass that along to the DOM using ref forwarding.
You can also add a wrapper DOM node in your component and attach a ref directly to it.
In CSS, the display: contents attribute can be used if you don’t want the node to be part of the layout.
Detecting unexpected side effects
Conceptually, React does work in two phases:
The commit phase is usually very fast, but rendering can be slow. For this reason, the upcoming async mode (which is not enabled by default yet) breaks the rendering work into pieces, pausing and resuming the work to avoid blocking the browser. This means that React may invoke render phase lifecycles more than once before committing, or it may invoke them without committing at all (because of an error or a higher priority interruption).
Render phase lifecycles include the following class component methods:
Because the above methods might be called more than once, it’s important that they do not contain side-effects. Ignoring this rule can lead to a variety of problems, including memory leaks and invalid application state. Unfortunately, it can be difficult to detect these problems as they can often be non-deterministic.
Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following methods:
This only applies to development mode. Lifecycles will not be double-invoked in production mode.
For example, consider the following code:
At first glance, this code might not seem problematic. But if SharedApplicationState.recordEvent is not idempotent, then instantiating this component multiple times could lead to invalid application state. This sort of subtle bug might not manifest during development, or it might do so inconsistently and so be overlooked.
By intentionally double-invoking methods like the component constructor, strict mode makes patterns like this easier to spot.
Detecting legacy context API
The legacy context API is error-prone, and will be removed in a future major version. It still works for all 16.x releases but will show this warning message in strict mode:
Read the new context API documentation to help migrate to the new version.