Рассмотрим пример работы React приложения без использования конкурентного рендеринга.
На картинке мы рендерим дерево React компонентов, один за другим. Каждый компонент рендерится по очереди, React не останавливает работу рендера, поэтому все компоненты получают одинаковое значение стора. После рендера всех компонентов, React освобождается и на 4ом шаге может изменить состояние стора
На картинке мы рендерим дерево React компонентов, один за другим. Каждый компонент рендерится по очереди, React не останавливает работу рендера, поэтому все компоненты получают одинаковое значение стора. После рендера всех компонентов, React освобождается и на 4ом шаге может изменить состояние стора
Пример работы React приложения с использованием конкурентного рендеринга.
В основном работа конкурентного ренедеринга не вызывает никаких проблем с консистентностью отображения данных, но бывают граничные случаи, когда это возможно.
Мы начинаем рендер дерева React компонентов, и рендерим первый компонент. Т.к. мы используем конкурентный рендеринг, React может остановить работу по рендеру компонентов, даже когда она не закончена. Это большой плюс к отзывчивости интерфейса, пользователь может сделать клик по кнопке и сразу увидеть результат.
Следствием этого подхода является то, что в результате пользовательского клика (или другой асинхронной работы, например ответ по сети или timeout) может измениться значение стора, которое используется компонентами для рендера. Это и есть граничный случай, который может спровоцировать проблемы.
В основном работа конкурентного ренедеринга не вызывает никаких проблем с консистентностью отображения данных, но бывают граничные случаи, когда это возможно.
Мы начинаем рендер дерева React компонентов, и рендерим первый компонент. Т.к. мы используем конкурентный рендеринг, React может остановить работу по рендеру компонентов, даже когда она не закончена. Это большой плюс к отзывчивости интерфейса, пользователь может сделать клик по кнопке и сразу увидеть результат.
Следствием этого подхода является то, что в результате пользовательского клика (или другой асинхронной работы, например ответ по сети или timeout) может измениться значение стора, которое используется компонентами для рендера. Это и есть граничный случай, который может спровоцировать проблемы.
На 2ом шаге можно увидеть, что React остановил рендер и изменил значение стора из-за клика пользователя. Проблема в том, что первый компонент отрендерился синим (на момент рендера значение стора было синим), но остальные компоненты при рендере получат текущее значение, которое является красным.
На последнем шаге компоненты, которые раньше всегда были синие, отображаются как микс из синих и красных компонентов. Они отображают два разных значения для одних и тех же данных. Это и есть разрыв интерфейса.
https://github.com/reactwg/react-18/discussions/69
На последнем шаге компоненты, которые раньше всегда были синие, отображаются как микс из синих и красных компонентов. Они отображают два разных значения для одних и тех же данных. Это и есть разрыв интерфейса.
https://github.com/reactwg/react-18/discussions/69
Библиотеки для анимации интерфейсов
- Framer Motion. Поддерживает декларативное описание анимаций, переходы и обработку жестов, серверный рендеринг. Можно управлять анимацией вручную и отслеживать состояние через MotionValues. Позволяет интерполировать значения через хук useTransform. Подробная документация, много готовых примеров. Напоминает библиотеку анимаций для React Native.
- react-spring. Одна из самых популярных библиотек для анимаций в React, содержит большое количество настроек для создания любого вида анимаций. Поддерживает интерполяцию данных, имеет возможность запуска серии зависимых друг от друга анимаций, плавные переходы. Помимо технических характеристик, у библиотеки большое комьюнити.
- React Transition Group. Набор компонентов для управления переходами в приложение. Имеет достаточно простые настройки, позволяет управлять анимацией переключением CSS классов.
- react-animations. Набор анимаций из библиотеки animate.css, может использоваться с любой встраиваемой библиотекой стилей.
- Framer Motion. Поддерживает декларативное описание анимаций, переходы и обработку жестов, серверный рендеринг. Можно управлять анимацией вручную и отслеживать состояние через MotionValues. Позволяет интерполировать значения через хук useTransform. Подробная документация, много готовых примеров. Напоминает библиотеку анимаций для React Native.
- react-spring. Одна из самых популярных библиотек для анимаций в React, содержит большое количество настроек для создания любого вида анимаций. Поддерживает интерполяцию данных, имеет возможность запуска серии зависимых друг от друга анимаций, плавные переходы. Помимо технических характеристик, у библиотеки большое комьюнити.
- React Transition Group. Набор компонентов для управления переходами в приложение. Имеет достаточно простые настройки, позволяет управлять анимацией переключением CSS классов.
- react-animations. Набор анимаций из библиотеки animate.css, может использоваться с любой встраиваемой библиотекой стилей.
Material UI обновилась до 5 версии
- Новый бренд: Material UI теперь будет называться MUI.
- В новой версии был сделан упор на улучшение кастомизации компонентов. Одно из больших изменений - это возможность выбора библиотеки для работы со стилями. Теперь по умолчанию, вместо JSS используется Emotion. Так же можно выбрать styled-components или остаться на JSS, либо выбрать любую другую библиотеку, если есть адаптер.
- Компоненты без стилей. Добавили набор хуков, которые реализуют логику базовых компонент (кнопки, автокомплит, слайдеры), с помощью которых можно самостоятельно собирать компоненты, со своими стилями. Позволяет хорошо сэкономить время при разработке своей дизайн-системы.
- Мигрировали свои тесты с Enzyme на Testing Library.
https://mui.com/blog/mui-core-v5/
- Новый бренд: Material UI теперь будет называться MUI.
- В новой версии был сделан упор на улучшение кастомизации компонентов. Одно из больших изменений - это возможность выбора библиотеки для работы со стилями. Теперь по умолчанию, вместо JSS используется Emotion. Так же можно выбрать styled-components или остаться на JSS, либо выбрать любую другую библиотеку, если есть адаптер.
- Компоненты без стилей. Добавили набор хуков, которые реализуют логику базовых компонент (кнопки, автокомплит, слайдеры), с помощью которых можно самостоятельно собирать компоненты, со своими стилями. Позволяет хорошо сэкономить время при разработке своей дизайн-системы.
- Мигрировали свои тесты с Enzyme на Testing Library.
https://mui.com/blog/mui-core-v5/
Универсальные компоненты
Если вы задумывались о разработке собственной библиотеки компонентов, то прежде чем начать её делать, стоит посмотреть в сторону библиотек универсальных компонентов. Существуют несколько таких библиотек. Разработчики из Adobe создали React Aria, MUI в 5 версии добавили unstyled components, в Яндексе начали заниматься разработкой универсальной дизайн-системы.
Библиотеки предоставляют коллекцию кастомных хуков для реализации базовых примитивов интерфейса. Хуки инкапсулируют в себе логику поведения элемента интерфейса и возвращают необходимые пропсы для отображения, учитывая правила доступности A11Y. Разработчикам, использующим данную библиотеку, нужно сфокусироваться только на дизайне для компонентов.
Хорошая возможность для быстрой разработки своей дизайн-системы.
Если вы задумывались о разработке собственной библиотеки компонентов, то прежде чем начать её делать, стоит посмотреть в сторону библиотек универсальных компонентов. Существуют несколько таких библиотек. Разработчики из Adobe создали React Aria, MUI в 5 версии добавили unstyled components, в Яндексе начали заниматься разработкой универсальной дизайн-системы.
Библиотеки предоставляют коллекцию кастомных хуков для реализации базовых примитивов интерфейса. Хуки инкапсулируют в себе логику поведения элемента интерфейса и возвращают необходимые пропсы для отображения, учитывая правила доступности A11Y. Разработчикам, использующим данную библиотеку, нужно сфокусироваться только на дизайне для компонентов.
Хорошая возможность для быстрой разработки своей дизайн-системы.
Adobe
React Aria
Craft world-class accessible components with custom styles.
Реальный пример работы startTransition
Ricky Hanlon показал подробный пример работы API startTransition из React 18, с объяснением работы API и того, как работает приложение в perfomance профиле.
В примере показан слайдер и компонент с «тяжелыми вычислениями», который занимает много времени для рендера, особенно на слабых устройствах. После изменения значения слайдера происходил ререндер тяжелого компонента. Самый оптимальный вариант рендера тяжелого компонента в React 17 через debounce, т.е. откладывая рендер на изменения слайдера.
В React 18 изменение значения слайдера достаточно обернуть в startTransition, и React уже сам выполнит эффективный рендер компонента. После рендера изменения значения слайдера, React рендерит transition результатов. Так как в этом изменение включен параллельный рендеринг, React делает три новые вещи:
- Yielding: каждые 5 мс React ставит работу рендера на паузу, чтобы дать браузеру сделать другую работу, например запустить промисы.
- Прерывание: React ставит рендер на паузу, если необходимо отрендерить более приоритетный компонент, например ползунок слайдера из примера.
- Отбрасывание старых результатов: когда React начинает рендерить после прерывания, то он отбрасывает старый компонент и рендерит новый.
https://github.com/reactwg/react-18/discussions/65
Ricky Hanlon показал подробный пример работы API startTransition из React 18, с объяснением работы API и того, как работает приложение в perfomance профиле.
В примере показан слайдер и компонент с «тяжелыми вычислениями», который занимает много времени для рендера, особенно на слабых устройствах. После изменения значения слайдера происходил ререндер тяжелого компонента. Самый оптимальный вариант рендера тяжелого компонента в React 17 через debounce, т.е. откладывая рендер на изменения слайдера.
В React 18 изменение значения слайдера достаточно обернуть в startTransition, и React уже сам выполнит эффективный рендер компонента. После рендера изменения значения слайдера, React рендерит transition результатов. Так как в этом изменение включен параллельный рендеринг, React делает три новые вещи:
- Yielding: каждые 5 мс React ставит работу рендера на паузу, чтобы дать браузеру сделать другую работу, например запустить промисы.
- Прерывание: React ставит рендер на паузу, если необходимо отрендерить более приоритетный компонент, например ползунок слайдера из примера.
- Отбрасывание старых результатов: когда React начинает рендерить после прерывания, то он отбрасывает старый компонент и рендерит новый.
https://github.com/reactwg/react-18/discussions/65
GitHub
Real world example: adding startTransition for slow renders · reactwg react-18 · Discussion #65
In React 18 we announced a new startTransition API and shared a high-level overview of the problem it solves. In this post, we’re going to dive into a real-world example of speeding up a slow updat...
Redux Toolkit на замену Redux
Если вы планируете использовать Redux в проекте, то рекомендую присмотреться к Redux Toolkit. Инструмент решает основные боли Redux, такие как лишний бойлерплейт и сложная настройка, а так же добавляет дополнительный функционал для работы со стором - слайсы.
Слайс представляет собой изолированную часть общего состояния стора, и автоматически генерирует action creators и action типы для соответствующих редьюсеров.
RTK Query - модуль для работы с сетевыми запросами и кэшированием, является частью Redux Toolkit. Возможности инструмента: простое получение и изменение данных, получение состояния запроса, оптимистичные обновления, управление кэшем запросов.
Предоставляет удобное API для создания и настройки запросов, а так же генерирует хуки, инкапсулирующие процесс получения данных, которые используются в компонентах.
Преимущества библиотеки: полностью написана на TypeScript, хорошая документация, большое комьюнити.
https://redux-toolkit.js.org/introduction/getting-started
Если вы планируете использовать Redux в проекте, то рекомендую присмотреться к Redux Toolkit. Инструмент решает основные боли Redux, такие как лишний бойлерплейт и сложная настройка, а так же добавляет дополнительный функционал для работы со стором - слайсы.
Слайс представляет собой изолированную часть общего состояния стора, и автоматически генерирует action creators и action типы для соответствующих редьюсеров.
RTK Query - модуль для работы с сетевыми запросами и кэшированием, является частью Redux Toolkit. Возможности инструмента: простое получение и изменение данных, получение состояния запроса, оптимистичные обновления, управление кэшем запросов.
Предоставляет удобное API для создания и настройки запросов, а так же генерирует хуки, инкапсулирующие процесс получения данных, которые используются в компонентах.
Преимущества библиотеки: полностью написана на TypeScript, хорошая документация, большое комьюнити.
https://redux-toolkit.js.org/introduction/getting-started
redux-toolkit.js.org
Getting Started | Redux Toolkit
Инструменты для отладки React приложений
Если приложение работает медленно, то для поиска причины тормозов можно использовать специальные инструменты:
- React DevTools. Базовый инструмент отладки React приложения. Умеет снимать perfomance профиль приложения, показать какой компонент отрендерился и сколько времени на это потребовалось.
- Why Did You Render (WDYR). Стандартного React DevTools может не хватать, поэтому в процесс отладки можно добавить WDYR. Этот инструмент находит компоненты, рендер которых можно избежать. Например, значением пропса компонента объявляется объект, поэтому этот компонент будет рендерится каждый раз, когда компонент создается. Найденную информацию WDYR отправляет в логи браузера.
- React Render Tracker. Инструмент для отслеживания производительности приложения Романа Дворнова. Умеет отслеживать изменения выбранного компонента, причину рендера, тайминги рендера компонента и его поддерева. Хороший UI, простая установка.
Если приложение работает медленно, то для поиска причины тормозов можно использовать специальные инструменты:
- React DevTools. Базовый инструмент отладки React приложения. Умеет снимать perfomance профиль приложения, показать какой компонент отрендерился и сколько времени на это потребовалось.
- Why Did You Render (WDYR). Стандартного React DevTools может не хватать, поэтому в процесс отладки можно добавить WDYR. Этот инструмент находит компоненты, рендер которых можно избежать. Например, значением пропса компонента объявляется объект, поэтому этот компонент будет рендерится каждый раз, когда компонент создается. Найденную информацию WDYR отправляет в логи браузера.
- React Render Tracker. Инструмент для отслеживания производительности приложения Романа Дворнова. Умеет отслеживать изменения выбранного компонента, причину рендера, тайминги рендера компонента и его поддерева. Хороший UI, простая установка.
Slate.js - настраиваемый текстовый редактор
При разработке библиотеки, автор был вдохновлен Draft.js, Prosemirror и Quill, но его не устраивала монолитная архитектура библиотек, сложность кастомизации и добавления своих элементов, ограничение в создании сложных документов с таблицами и вложенными объектами.
Особенности редактора:
- Кастомизация. Slate.js разработана на плагинах, можно легко расширить текущий функционал библиотеки самостоятельно.
- Слабая схема данных. Не важно с какими данными вы работаете, что упрощает создание более сложных редакторов, чем базовый.
- Вложенная модель документа. Slate.js использует модель документа похожую на DOM и предоставляет стандартные обработчики событий. Это означает, что возможно создание более сложных компонентов, например таблицы.
- Коллективная работа. Модель данных спроектирована таким образом, что позволяет работать коллективно над одним документом, например как в гугл документах. Пример.
https://github.com/ianstormtaylor/slate
При разработке библиотеки, автор был вдохновлен Draft.js, Prosemirror и Quill, но его не устраивала монолитная архитектура библиотек, сложность кастомизации и добавления своих элементов, ограничение в создании сложных документов с таблицами и вложенными объектами.
Особенности редактора:
- Кастомизация. Slate.js разработана на плагинах, можно легко расширить текущий функционал библиотеки самостоятельно.
- Слабая схема данных. Не важно с какими данными вы работаете, что упрощает создание более сложных редакторов, чем базовый.
- Вложенная модель документа. Slate.js использует модель документа похожую на DOM и предоставляет стандартные обработчики событий. Это означает, что возможно создание более сложных компонентов, например таблицы.
- Коллективная работа. Модель данных спроектирована таким образом, что позволяет работать коллективно над одним документом, например как в гугл документах. Пример.
https://github.com/ianstormtaylor/slate
Почему нужно везде использовать мемоизацию
Stefano J. Attardi из Coinbase рассказал в своем блоге, что на проектах все компоненты оборачивают в memo. Краткие доводы в пользу такого подхода:
- Дорогой ререндер. Если не использовать memo, то React будет вызывать рендер компонента, выделять память на колбеки и элементы, а так же рендерить дочерние компоненты. После чего, React должен потратить время на сравнение старого и нового дерева компонентов.
- Использование memo не влияет на производительность. React устроен так, что хранит предыдущие пропсы компонента, поэтому использование memo не увеличивает использование памяти.
- Используйте useCallback и useMemo. При использовании memo необходимо мемоизировать все пропсы компонента.
https://attardi.org/why-we-memo-all-the-things/
Stefano J. Attardi из Coinbase рассказал в своем блоге, что на проектах все компоненты оборачивают в memo. Краткие доводы в пользу такого подхода:
- Дорогой ререндер. Если не использовать memo, то React будет вызывать рендер компонента, выделять память на колбеки и элементы, а так же рендерить дочерние компоненты. После чего, React должен потратить время на сравнение старого и нового дерева компонентов.
- Использование memo не влияет на производительность. React устроен так, что хранит предыдущие пропсы компонента, поэтому использование memo не увеличивает использование памяти.
- Используйте useCallback и useMemo. При использовании memo необходимо мемоизировать все пропсы компонента.
https://attardi.org/why-we-memo-all-the-things/
attardi.org
Why We Memo All the Things
On my team at Coinbase, we ask everyone to use the React performance trinity – memo, useMemo, and useCallback – all the time. For some reason, this is controversial. I’m guessing this has something to do with Twitter. This article explains why we do it anyway.
Библиотеки для работы с формами в React
- Formik. Одна из наиболее популярных библиотек для работы с формами. Умеет отправлять форму асинхронно, поддерживает TypeScript, а также валидацию через Yup или Joi. В Formik входит набор компонентов для создания формы: Form, Field, ErrorMessage, но так же форму можно создать используя хук useFormik.
- React Hook Form. Гибкая библиотека для создания форм черех хуки. Поддерживает TypeScript и React Native. Умеет делать валидацию полей и формы, подключается к нативным инпутам через ref атрибут. Если инпут кастомный, например, из Material UI, то предлагает использовать обертку в виде компонента Controller.
- React Final Form. Библиотека использует паттерн Observer для обновления состояния компонентов и ре-рендера. Поддерживает валидацию полей и формы, в состав библиотеки входят как компоненты Form, Field, так и хуки. Мейнтенер библиотеки Erik Rasmussen, который также был автором Redux Form, считает ключевой фичей React Final Form высокую производительность.
- Formik. Одна из наиболее популярных библиотек для работы с формами. Умеет отправлять форму асинхронно, поддерживает TypeScript, а также валидацию через Yup или Joi. В Formik входит набор компонентов для создания формы: Form, Field, ErrorMessage, но так же форму можно создать используя хук useFormik.
- React Hook Form. Гибкая библиотека для создания форм черех хуки. Поддерживает TypeScript и React Native. Умеет делать валидацию полей и формы, подключается к нативным инпутам через ref атрибут. Если инпут кастомный, например, из Material UI, то предлагает использовать обертку в виде компонента Controller.
- React Final Form. Библиотека использует паттерн Observer для обновления состояния компонентов и ре-рендера. Поддерживает валидацию полей и формы, в состав библиотеки входят как компоненты Form, Field, так и хуки. Мейнтенер библиотеки Erik Rasmussen, который также был автором Redux Form, считает ключевой фичей React Final Form высокую производительность.
Пример использования useDeferredValue
Дэн Абрамов поделился примером использования хука useDeferredValue из React 18:
Используйте
Дэн Абрамов поделился примером использования хука useDeferredValue из React 18:
function Form() {
const [state, setState] = useState({ value: "hello" })
const deferredState = useDeferredValue(state)
// ...
Используйте
deferredState в компонентах, рендер которых не срочный: например, вычисление сложной логики. Это поведение напоминает debounce. Использовать state напрямую можно в элементах пользовательского ввода, например, input.GitHub
Patterns for startTransition · reactwg/react-18 · Discussion #100
One major use case for startTransition is to update an input instantaneously while things that depend on that input's value are possibly delayed: function TransInput({ value, onChange }) { cons...
Эффективное использование контекста
Kent C. Dodds делится идеей использования контекста. Контекст не обязательно должен быть глобальным на всë приложение, контекст может быть частью определенной ветви приложения.
При создании контекста оборачивайте провайдер и потребитель в обертку. Провайдер-обертка - HoC, в котором инициализируется состояние контекста. Польза такого подхода в том, что эта логика инкапсулируется в одном месте. Потребитель-обертка - HoC или кастомный хук, в котором добавляется проверка значения контекста, и можно вывести ошибку.
Используйте мемоизацию для значения контекста в провайдере, чтобы избежать лишних рендеров компонента.
https://kentcdodds.com/blog/how-to-use-react-context-effectively
Kent C. Dodds делится идеей использования контекста. Контекст не обязательно должен быть глобальным на всë приложение, контекст может быть частью определенной ветви приложения.
При создании контекста оборачивайте провайдер и потребитель в обертку. Провайдер-обертка - HoC, в котором инициализируется состояние контекста. Польза такого подхода в том, что эта логика инкапсулируется в одном месте. Потребитель-обертка - HoC или кастомный хук, в котором добавляется проверка значения контекста, и можно вывести ошибку.
Используйте мемоизацию для значения контекста в провайдере, чтобы избежать лишних рендеров компонента.
https://kentcdodds.com/blog/how-to-use-react-context-effectively
Kentcdodds
How to use React Context effectively
How to create and expose React Context providers and consumers
Как работает обработка ошибок в React
Хорошая обзорная статья о том, как обрабатываются ошибки в React. Разобраны причины, почему стандартный try/catch внутри render() не работает, и почему нужно использовать Error Boundaries.
Причина по которой стандартный try/catch не работает внутри render() заключается в принципе работы архитектуры React Fiber. Когда вызывается рендер компонента, React не сразу выполняет эту работу, а ставит в очередь работ. Рендер компонента происходит внутри workLoop, а вызов функции рендера обернут в try/catch. Если произошла ошибка рендера, то React ищет ближайшего родителя с необходимыми методами (getDerivedStateFromError или componentDidCatch) и передает ему возможность обработки ошибки.
https://habr.com/ru/company/2gis/blog/583894/
Хорошая обзорная статья о том, как обрабатываются ошибки в React. Разобраны причины, почему стандартный try/catch внутри render() не работает, и почему нужно использовать Error Boundaries.
Причина по которой стандартный try/catch не работает внутри render() заключается в принципе работы архитектуры React Fiber. Когда вызывается рендер компонента, React не сразу выполняет эту работу, а ставит в очередь работ. Рендер компонента происходит внутри workLoop, а вызов функции рендера обернут в try/catch. Если произошла ошибка рендера, то React ищет ближайшего родителя с необходимыми методами (getDerivedStateFromError или componentDidCatch) и передает ему возможность обработки ошибки.
https://habr.com/ru/company/2gis/blog/583894/
Хабр
Error Boundaries в React: препарируем лягушку
Представим, что у нас есть приложение на React, в котором можно читать и писать отзывы. Пользователь открыл список отзывов, пролистал его, нажал кнопку «Написать отзыв». Форма написания отзыва...
👍1
Причины рендера приложения
При оптимизации работы приложения важно уделить внимание причинам рендера компонентов. Алекс Сидоренко в своем блоге разобрал причины рендера компонентов в React и подготовил небольшую шпаргалку. Разберем основные причины рендера, и как их исправить:
- Изменение состояния в родителе. По умолчанию, если меняется состояние в компоненте, то компонент и все дочерние элементы ре-рендерятся. Чтобы не рендерить дочерние компоненты, необходимо их обернуть в memo.
- Передача нового объекта в дочерний компонент. Объекты передаются по ссылке, поэтому если в родителе объявляется объект, с каждым рендером создается новая ссылка, которая не равна предыдущей. Поэтому, если даже дочерний компонент обернут в memo, то будет происходит его ре-рендер. Используйте useMemo и useCallback для передачи объектов дочерним компонентам.
- Изменение значения контекста. Здесь похожая ситуация с первой причиной рендера. При изменении состояния компонента, дочерние компоненты ре-рендерятся. Чтобы избежать лишнего ре-рендера, нужно обернуть в memo компонент, который является дочерним у контекст-провайдера.
Не стоит забывать, что сам по себе рендер приложения не является чем-то плохим. Важно, чтобы рендер приложения не занимал много времени, иначе это может привести к фризам интерфейса сайта.
https://alexsidorenko.com/blog/react-render-cheat-sheet/
При оптимизации работы приложения важно уделить внимание причинам рендера компонентов. Алекс Сидоренко в своем блоге разобрал причины рендера компонентов в React и подготовил небольшую шпаргалку. Разберем основные причины рендера, и как их исправить:
- Изменение состояния в родителе. По умолчанию, если меняется состояние в компоненте, то компонент и все дочерние элементы ре-рендерятся. Чтобы не рендерить дочерние компоненты, необходимо их обернуть в memo.
- Передача нового объекта в дочерний компонент. Объекты передаются по ссылке, поэтому если в родителе объявляется объект, с каждым рендером создается новая ссылка, которая не равна предыдущей. Поэтому, если даже дочерний компонент обернут в memo, то будет происходит его ре-рендер. Используйте useMemo и useCallback для передачи объектов дочерним компонентам.
- Изменение значения контекста. Здесь похожая ситуация с первой причиной рендера. При изменении состояния компонента, дочерние компоненты ре-рендерятся. Чтобы избежать лишнего ре-рендера, нужно обернуть в memo компонент, который является дочерним у контекст-провайдера.
Не стоит забывать, что сам по себе рендер приложения не является чем-то плохим. Важно, чтобы рендер приложения не занимал много времени, иначе это может привести к фризам интерфейса сайта.
https://alexsidorenko.com/blog/react-render-cheat-sheet/
Alex Sidorenko
A Visual Guide to React Rendering - Cheat Sheet | Alex Sidorenko
A quick cheat sheet to React rendering mechanism
Хуки react-router
Используя библиотеку react-router для получения текущего состояния роутера и выполнения навигации, можно использовать кастомные хуки, которые входят в react-router-dom:
- useHistory. Возвращает объект history, который позволяет изменить состояние роутера. Например, можно перенаправить пользователя на другой URL, либо вернуться на предыдущую страницу.
- useLocation. Возвращает объект location, представляющий текущий URL. Этот хук аналогичен useState, который возвращает новый объект location при смене текущего URL.
- useParams. Хук для доступа к параметрам URL, который установлен в роуте.
- useRouteMatch. Этот хук пытается сопоставить текущий URL таким же образом, как и <Route>. Может использоваться взамен компонента <Route>, если необходимо отрендерить что-то при заданном URL.
- useQuery. Хук не входит в список стандартных, но его можно реализовать используя useLocation.
https://reactrouter.com/web/api/Hooks
Используя библиотеку react-router для получения текущего состояния роутера и выполнения навигации, можно использовать кастомные хуки, которые входят в react-router-dom:
- useHistory. Возвращает объект history, который позволяет изменить состояние роутера. Например, можно перенаправить пользователя на другой URL, либо вернуться на предыдущую страницу.
- useLocation. Возвращает объект location, представляющий текущий URL. Этот хук аналогичен useState, который возвращает новый объект location при смене текущего URL.
- useParams. Хук для доступа к параметрам URL, который установлен в роуте.
- useRouteMatch. Этот хук пытается сопоставить текущий URL таким же образом, как и <Route>. Может использоваться взамен компонента <Route>, если необходимо отрендерить что-то при заданном URL.
- useQuery. Хук не входит в список стандартных, но его можно реализовать используя useLocation.
https://reactrouter.com/web/api/Hooks
Кастомный React рендерер
Когда React рендерит приложение и обновляет DOM, то используется React DOM. При рендере приложения на сервере используется модуль
Таким образом, для каждого окружения используется свой рендерер, хотя модуль
Модуль
Для разработки своего рендерера необходимо описать объект “host config”, в котором описаны методы реализации API React. Выглядит так:
https://github.com/facebook/react/blob/main/packages/react-reconciler/README.md
Когда React рендерит приложение и обновляет DOM, то используется React DOM. При рендере приложения на сервере используется модуль
react-dom/server. Для мобильных приложений для рендера используется модуль react-native. Таким образом, для каждого окружения используется свой рендерер, хотя модуль
react используется везде один. Модуль
react предоставляет API для определения компонентов, а реализация находится в “рендерерах”. Для связи хуков с реализацией используется объект “диспатчер”. При вызове useState, вызов перенаправляется текущему диспатчеру рендерера. Об этом есть подробная статья в блоге Дэна Абрамова.Для разработки своего рендерера необходимо описать объект “host config”, в котором описаны методы реализации API React. Выглядит так:
const HostConfig = {
createInstance(type, props) {
// e.g. DOM renderer returns a DOM node
},
// ...
supportsMutation: true, // it works by mutating nodes
appendChild(parent, child) {
// e.g. DOM renderer would call .appendChild() here
},
// ...
};
https://github.com/facebook/react/blob/main/packages/react-reconciler/README.md
overreacted.io
How Does setState Know What to Do? — overreacted
Dependency injection is nice if you don’t have to think about it.
Копия Windows 11 на React
Опенсорсная копия Windows 11, работающая в браузере и написанная с использованием React.
По большому счету представляет собой просто набор экранов Windows 11 с очень ограниченным функционалом. Но тем не менее, выглядит реалистично и очень красиво.
https://github.com/blueedgetechno/win11React
https://win11.blueedge.me/
Опенсорсная копия Windows 11, работающая в браузере и написанная с использованием React.
По большому счету представляет собой просто набор экранов Windows 11 с очень ограниченным функционалом. Но тем не менее, выглядит реалистично и очень красиво.
https://github.com/blueedgetechno/win11React
https://win11.blueedge.me/
GitHub
GitHub - blueedgetechno/win11React: Windows 11 in React 💻🌈⚡
Windows 11 in React 💻🌈⚡. Contribute to blueedgetechno/win11React development by creating an account on GitHub.
Библиотека SWR для получения данных
SWR происходит от stale-while-revalidate, это стратегия кэширования ресурсов, в котором сначала возвращаются данные из кэша, а потом происходит запрос на получение свежих данных. Преимущество такой стратегии кэширования заключается в увеличении видимой производительности сайта, пользователям приходится меньше ждать и видеть спиннеры загрузки.
Библиотека представляет из себя набор хуков, основной из которых это
Особенности библиотеки: поддержка стратегии SWR, автоматическая ревалидация кэша, поддержка API Suspense. Авторами библиотеки являются разработчики Next.js.
https://swr.vercel.app/
SWR происходит от stale-while-revalidate, это стратегия кэширования ресурсов, в котором сначала возвращаются данные из кэша, а потом происходит запрос на получение свежих данных. Преимущество такой стратегии кэширования заключается в увеличении видимой производительности сайта, пользователям приходится меньше ждать и видеть спиннеры загрузки.
Библиотека представляет из себя набор хуков, основной из которых это
useSWR. Помимо получения данных, есть возможность изменения данных. Изменение данных также возможно по стратегии SWR - сначала локально, потом отправляем запрос на сервер. Особенности библиотеки: поддержка стратегии SWR, автоматическая ревалидация кэша, поддержка API Suspense. Авторами библиотеки являются разработчики Next.js.
https://swr.vercel.app/
Lazy Loading для увеличения скорости загрузки сайта
При загрузке сайта пользователю требуются не все ресурсы сразу. Принцип отложенной загрузки заключается в откладывании загрузки ресурсов, которые сейчас не важны пользователю. Когда отложенный ресурс понадобится, то он будет сразу загружен. Шаблон отложенной загрузки можно применить на изображения, видео и отдельные страницы сайта.
В React есть две функции, позволяющие легко интегрировать отложенную загрузку:
При загрузке сайта пользователю требуются не все ресурсы сразу. Принцип отложенной загрузки заключается в откладывании загрузки ресурсов, которые сейчас не важны пользователю. Когда отложенный ресурс понадобится, то он будет сразу загружен. Шаблон отложенной загрузки можно применить на изображения, видео и отдельные страницы сайта.
В React есть две функции, позволяющие легко интегрировать отложенную загрузку:
React.lazy() и React.Suspense. React.lazy() это функция, которая позволяет отрендерить динамический импорт как обычный компонент. Динамический импорт – это способ разделения кода, основной подход в реализации отложенной загрузки.