StrictMode¶
Режим <StrictMode>
позволяет находить распространенные ошибки в компонентах на ранних стадиях разработки.
1 2 3 |
|
Описание¶
<StrictMode>
¶
Используйте StrictMode
для включения дополнительных поведений разработки и предупреждений для внутреннего дерева компонентов:
1 2 3 4 5 6 7 8 9 |
|
Строгий режим включает следующие модели поведения, доступные только для разработчиков:
- Ваши компоненты будут перерендериваться дополнительно для поиска ошибок, вызванных нечистым рендерингом.
- Ваши компоненты будут перезапускать эффекты дополнительно, чтобы найти ошибки, вызванные отсутствием очистки эффектов.
- Ваши компоненты будут проверяться на использование устаревших API.
Пропсы¶
StrictMode
не принимает никаких пропсов.
Предупреждения¶
- Не существует способа отказаться от строгого режима внутри дерева, обернутого в
<StrictMode>
. Это дает уверенность в том, что все компоненты внутри<StrictMode>
проверены. Если две команды, работающие над продуктом, расходятся во мнении, считают ли они проверки ценными, им нужно либо прийти к консенсусу, либо переместить<StrictMode>
вниз в дереве.
Использование¶
Включение строгого режима для всего приложения¶
Строгий режим включает дополнительные проверки, предназначенные только для разработчиков, для всего дерева компонентов внутри компонента <StrictMode>
. Эти проверки помогут вам найти распространенные ошибки в ваших компонентах на ранних стадиях разработки.
Чтобы включить режим Strict Mode для всего приложения, оберните корневой компонент компонентом <StrictMode>
при его рендеринге:
1 2 3 4 5 6 7 8 9 |
|
Мы рекомендуем обернуть все ваше приложение в режим Strict Mode, особенно для вновь созданных приложений. Если вы используете фреймворк, который вызывает для вас createRoot
, ознакомьтесь с его документацией, чтобы узнать, как включить строгий режим.
Хотя проверки в строгом режиме работают только в разработке, они помогают найти ошибки, которые уже существуют в вашем коде, но могут быть трудно воспроизводимы в производстве. Строгий режим позволяет исправлять ошибки до того, как пользователи сообщат о них.
Проверки строгого режима
Строгий режим включает следующие проверки в процессе разработки:
- Ваши компоненты будут перерендериваться дополнительно для поиска ошибок, вызванных нечистым рендерингом.
- Ваши компоненты будут перезапускать эффекты дополнительно, чтобы найти ошибки, вызванные отсутствием очистки эффектов.
- Ваши компоненты будут проверяться на использование устаревших API.
Все эти проверки предназначены только для разработки и не влияют на производственную сборку.
Включение строгого режима для части приложения¶
Вы также можете включить строгий режим для любой части вашего приложения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
В этом примере проверки строгого режима не будут выполняться для компонентов Header
и Footer
. Однако они будут выполняться для Sidebar
и Content
, а также для всех компонентов внутри них, независимо от их глубины.
Исправление ошибок, найденных при двойном рендеринге в разработке¶
React предполагает, что каждый написанный вами компонент является чистой функцией Это означает, что написанные вами компоненты React должны всегда возвращать один и тот же JSX при одинаковых входных данных (props, state и context).
Компоненты, нарушающие это правило, ведут себя непредсказуемо и вызывают ошибки. Чтобы помочь вам найти случайно нечистый код, Strict Mode вызывает некоторые из ваших функций (только те, которые должны быть чистыми) дважды в процессе разработки. Это включает в себя:
- тело функции вашего компонента (только логика верхнего уровня, поэтому сюда не входит код внутри обработчиков событий).
- Функции, которые вы передаете в
useState
,set
functions,useMemo
, илиuseReducer
. - Некоторые методы компонентов класса, такие как
constructor
,render
,shouldComponentUpdate
(посмотреть весь список).
Если функция чистая, то ее повторный запуск не изменит ее поведения, потому что чистая функция каждый раз выдает один и тот же результат. Однако, если функция нечистая (например, она мутирует полученные данные), ее повторный запуск будет заметен (вот что делает ее нечистой!) Это поможет вам обнаружить и исправить ошибку на ранней стадии.
Здесь приведен пример, иллюстрирующий, как двойной рендеринг в строгом режиме помогает найти ошибку на ранней стадии.
Этот компонент StoryTray
берет массив историй
и добавляет последний элемент "Create Story" в конце:
1 2 3 4 5 6 7 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
В приведенном выше коде есть ошибка. Однако ее легко не заметить, поскольку первоначальный вывод выглядит правильным.
Эта ошибка станет более заметной, если компонент StoryTray
будет рендериться несколько раз. Например, давайте заставим StoryTray
повторно отображаться с другим цветом фона при каждом наведении на него курсора:
1 2 3 4 5 6 7 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Обратите внимание, что каждый раз, когда вы наводите курсор на компонент StoryTray
, "Create Story" снова добавляется в список. Замысел кода заключался в том, чтобы добавить его один раз в конце. Но StoryTray
напрямую изменяет массив stories
из пропса. Каждый раз, когда StoryTray
рендерит, он снова добавляет "Create Story" в конец того же массива. Другими словами, StoryTray
не является чистой функцией - ее многократный запуск приводит к различным результатам.
Чтобы решить эту проблему, вы можете сделать копию массива и изменить эту копию вместо оригинальной:
1 2 3 4 |
|
Это сделает функцию StoryTray
чистой. При каждом вызове она будет модифицировать только новую копию массива и не будет влиять на внешние объекты или переменные. Это решает проблему, но вам придется заставлять компонент перерисовываться чаще, прежде чем станет очевидно, что в его поведении что-то не так.
В исходном примере ошибка не была очевидной. Теперь давайте обернем исходный (баговый) код в <StrictMode>
:.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
Строгий режим всегда вызывает вашу функцию рендеринга дважды, чтобы вы могли сразу увидеть ошибку ("Create Story" появляется дважды). Это позволяет заметить такие ошибки на ранней стадии процесса. Когда вы исправляете свой компонент для рендеринга в строгом режиме, вы также исправляете многие возможные будущие ошибки производства, такие как функциональность hover, о которой говорилось ранее:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Без режима Strict Mode ошибку легко было не заметить, пока вы не добавляли больше рендеров. В режиме Strict Mode та же ошибка появлялась сразу же. Режим Strict Mode помогает найти ошибки до того, как вы передадите их команде и пользователям.
Подробнее о поддержании чистоты компонентов.
React DevTools
Если у вас установлен React DevTools, все вызовы console.log
во время второго вызова рендеринга будут выглядеть слегка затемненными. React DevTools также предлагает настройку (по умолчанию выключена) для их полного подавления.
Исправление ошибок, найденных при повторном запуске эффектов в разработке¶
Строгий режим также может помочь найти ошибки в Эффектах.
Каждый Эффект имеет некоторый код настройки и может иметь некоторый код очистки. Обычно React вызывает setup, когда компонент mounts (добавляется на экран) и вызывает cleanup, когда компонент unmounts (удаляется с экрана). Затем React снова вызывает cleanup и setup, если его зависимости изменились с момента последнего рендеринга.
Когда включен строгий режим, React также будет выполнять один дополнительный цикл setup+cleanup в процессе разработки для каждого Effect. Это может показаться удивительным, но это помогает выявить тонкие ошибки, которые трудно обнаружить вручную.
Вот пример, иллюстрирующий, как повторный запуск Эффектов в строгом режиме помогает найти ошибки на ранней стадии..
Рассмотрим этот пример, который соединяет компонент с чатом:
1 2 3 4 5 6 7 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
В этом коде есть проблема, но она может быть не сразу понятна.
Чтобы сделать проблему более очевидной, давайте реализуем функцию. В приведенном ниже примере roomId
не является жестко закодированным. Вместо этого пользователь может выбрать roomId
, к которому он хочет подключиться, из выпадающего списка. Нажмите "Открыть чат", а затем выберите по очереди разные комнаты чата. Следите за количеством активных подключений в консоли:
1 2 3 4 5 6 7 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
Вы заметите, что количество открытых соединений постоянно растет. В реальном приложении это вызвало бы проблемы с производительностью и сетью. Проблема в том, что вашему Эффекту не хватает функции очистки:
1 2 3 4 5 |
|
Теперь, когда ваш Effect "убирает" за собой и уничтожает устаревшие связи, утечка решена. Однако обратите внимание, что проблема не стала заметной, пока вы не добавили больше возможностей (поле выбора).
В исходном примере ошибка не была очевидной. Теперь давайте обернем исходный (баговый) код в <StrictMode>
:.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
В строгом режиме вы сразу увидите, что есть проблема (количество активных соединений подскочит до 2). Строгий режим запускает дополнительный цикл настройки+очистки для каждого Эффекта. Этот Эффект не имеет логики очистки, поэтому он создает дополнительное соединение, но не уничтожает его. Это намек на то, что вам не хватает функции очистки.
Строгий режим позволяет заметить такие ошибки на ранней стадии процесса. Когда вы исправляете свой Эффект, добавляя функцию очистки в строгом режиме, вы также исправляете многие возможные будущие ошибки производства, такие как поле выбора из предыдущей версии:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
Обратите внимание, что количество активных соединений в консоли больше не растет.
Без режима Strict Mode можно было легко пропустить, что ваш Эффект нуждается в очистке. Выполняя setup → cleanup → setup вместо setup для вашего Эффекта в разработке, Строгий режим сделал недостающую логику очистки более заметной.
Подробнее о реализации очистки эффектов
Исправление предупреждений об устаревании, включенных в строгом режиме¶
React предупреждает, если какой-то компонент в любом месте дерева <StrictMode>
использует один из этих устаревших API:
findDOMNode
- См. альтернативы.- Методы жизненного цикла класса
UNSAFE_
, такие какUNSAFE_componentWillMount
- См. альтернативы. - Наследный контекст (
childContextTypes
,contextTypes
, иgetChildContext
) - См. альтернативы. - Legacy string refs (
this.refs
) - См. альтернативы.
Эти API в основном используются в старых компонентах классов, поэтому они редко появляются в современных приложениях.
Источник — https://react.dev/reference/react/StrictMode