Хуки 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() это функция, которая позволяет отрендерить динамический импорт как обычный компонент. Динамический импорт – это способ разделения кода, основной подход в реализации отложенной загрузки.Компонент, созданный
На данный момент единственный вариант использования Suspense –
React.lazy(), загружается только тогда, когда его нужно отрендерить. В процессе загрузки компонента нужно показать какой то плейсхолдер, например, спиннер загрузки. Для этих целей предназначен React.Suspense. На данный момент единственный вариант использования Suspense –
React.lazy(). Вероятнее всего, в React 18 появится возможность использовать Suspense для обработки получения данных из API.Отложенная загрузка по роутам
Помимо отложенной загрузки компонентов используя
Помимо отложенной загрузки компонентов используя
React.lazy() и React.Suspense можно реализовать отложенную загрузку роута приложения. Для этого необходимо конвертировать компоненты для роутов в “ленивые” компоненты роутов, а список всех роутов обернуть в Suspense.Отложенная загрузка на сервере
До React 18 Suspense не поддерживается в серверном рендеринге. Для разделения кода на стороне сервера используйте библиотеку react-loadable.
До React 18 Suspense не поддерживается в серверном рендеринге. Для разделения кода на стороне сервера используйте библиотеку react-loadable.
Как работает styled-components
Joshua Comeau подробно рассказал в своем блоге о принципах работы библиотеки styled-components.
- Фабрика компонентов. При создании styled-component используется каррирование, таким образом можно использовать не только стандартные HTML теги, но и кастомные компоненты.
- При композиции styled-component поддерживается порядок вставки стилей в документ.
- Оптимизация стилей. Для вставки стилей в документ используется CSSOM, сам процесс вставки стилей происходит в момент рендера компонента. Такой подход гарантирует, что в документе не будет лишних стилей.
- Интерполяция стилей. Если при интерполяции стилей у двух одинаковых styled-component передать разные значения пропсов для интерполяции, то сгенерируются два класса стилей. Этот подход плох тем, что раздувает размер стилей документа и при изменении пропса потребуется генерация новых стилей. В этом случае лучше использовать CSS переменные.
https://www.joshwcomeau.com/react/demystifying-styled-components/
Joshua Comeau подробно рассказал в своем блоге о принципах работы библиотеки styled-components.
- Фабрика компонентов. При создании styled-component используется каррирование, таким образом можно использовать не только стандартные HTML теги, но и кастомные компоненты.
- При композиции styled-component поддерживается порядок вставки стилей в документ.
- Оптимизация стилей. Для вставки стилей в документ используется CSSOM, сам процесс вставки стилей происходит в момент рендера компонента. Такой подход гарантирует, что в документе не будет лишних стилей.
- Интерполяция стилей. Если при интерполяции стилей у двух одинаковых styled-component передать разные значения пропсов для интерполяции, то сгенерируются два класса стилей. Этот подход плох тем, что раздувает размер стилей документа и при изменении пропса потребуется генерация новых стилей. В этом случае лучше использовать CSS переменные.
https://www.joshwcomeau.com/react/demystifying-styled-components/
Joshwcomeau
Demystifying styled-components • Josh W. Comeau
For so many React devs, styled-components seems kinda magical. It isn't at all clear how it uses traditional CSS features under-the-hood, and that lack of clarity can cause real problems when things go awry. In this post, we'll learn exactly how styled-components…
react-static – фреймворк для создания статических сайтов
react-static – простой в настройке генератор статических сайтов на React. Можно выделить следующие преимущества фреймворка:
- Независимость от данных. Все данные, необходимые для рендеринга сайта, заранее собираются в конфиг-файле. Источник данных может быть любой, хоть GraphQL или REST API. В компонентах доступ к данным происходит через хук или пропсы.
- Поддержка SPA. При загрузке статической страницы сайта загружается минимальный бандл для React. Помимо JS бандла загружаются остальные статические страницы и данные, а потом помещаются в кэш браузера. Благодаря такому подходу дальнейшие переходы по ссылкам будут происходить мгновенно, без перезагрузки страницы.
Похожие фреймворки: Gatsby и Next.js.
https://github.com/react-static/react-static
react-static – простой в настройке генератор статических сайтов на React. Можно выделить следующие преимущества фреймворка:
- Независимость от данных. Все данные, необходимые для рендеринга сайта, заранее собираются в конфиг-файле. Источник данных может быть любой, хоть GraphQL или REST API. В компонентах доступ к данным происходит через хук или пропсы.
- Поддержка SPA. При загрузке статической страницы сайта загружается минимальный бандл для React. Помимо JS бандла загружаются остальные статические страницы и данные, а потом помещаются в кэш браузера. Благодаря такому подходу дальнейшие переходы по ссылкам будут происходить мгновенно, без перезагрузки страницы.
Похожие фреймворки: Gatsby и Next.js.
https://github.com/react-static/react-static
GitHub
GitHub - react-static/react-static: ⚛️ 🚀 A progressive static site generator for React.
⚛️ 🚀 A progressive static site generator for React. - react-static/react-static
Антипаттерны React
Iskander Samatov в своём блоге рассказал об антипаттернах в React, которые чаще всего встречаются в приложениях и следует избегать:
- Хранить всё в Redux. Используйте глобальный стейт для данных, которые нужны всему приложению, например, сессия пользователя или текущая тема. Для остальных случаев используйте контекст на определенных частях приложения.
- Хранить всё как стейт. Прежде чем хранить переменную как стейт компонента, определите, можно ли вычислить эту переменную на основе других данных. Если возможно, то хранить переменную в стейте необязательно.
- Передавать пропсы используя spread оператор. Когда передаются пропсы компоненту через spread оператор {...props}, то это усложняет понимание кода. Становится непонятно, какие пропсы нужны компоненту. Исключением для правила является написание компонента контейнера и HOC.
- Объявление компонента внутри компонента. Код становится тесно связанным (high coupling), а также уменьшается производительность компонента, при каждом рендере компонента будет создаваться новый компонент.
https://isamatov.com/react-antipatterns/
Iskander Samatov в своём блоге рассказал об антипаттернах в React, которые чаще всего встречаются в приложениях и следует избегать:
- Хранить всё в Redux. Используйте глобальный стейт для данных, которые нужны всему приложению, например, сессия пользователя или текущая тема. Для остальных случаев используйте контекст на определенных частях приложения.
- Хранить всё как стейт. Прежде чем хранить переменную как стейт компонента, определите, можно ли вычислить эту переменную на основе других данных. Если возможно, то хранить переменную в стейте необязательно.
- Передавать пропсы используя spread оператор. Когда передаются пропсы компоненту через spread оператор {...props}, то это усложняет понимание кода. Становится непонятно, какие пропсы нужны компоненту. Исключением для правила является написание компонента контейнера и HOC.
- Объявление компонента внутри компонента. Код становится тесно связанным (high coupling), а также уменьшается производительность компонента, при каждом рендере компонента будет создаваться новый компонент.
https://isamatov.com/react-antipatterns/
Web Development Tutorials - Iskander Samatov
React antipatterns to avoid
These antipatterns will make your codebase a nightmare to work with.
useId для генерации уникальных ID
В React 18 появится новый хук для генерации уникальных id. Этот хук можно использовать для связки названия и инпута:
Проблема, которую решает хук useId, связана с новым подходом серверного рендеринга в React. Раньше для генерации уникальных id использовался простой счетчик. В новой версии React, при использовании конкурентного рендеринга, HTML может передаваться в произвольном порядке.
Для генерации уникальных id в хуке useId используется текущая позиция компонента в дереве приложения. Внутри React, id представляет из себя двоичное число. Для дочерних элементов добавляются дополнительные биты слева от последовательности родителя, которые представляет положение дочернего элемента на текущем уровне дочерних элементов.
Это позволяет быть уверенным, что каждый вызов useId будет возвращать уникальный id. Если в компоненте несколько лейблов и инпутов, то можно добавить локальные префиксы, что гарантирует уникальность id глобально:
Хотя так делать не обязательно, если несколько раз вызвать useId в одном компоненте, то каждый из них вернёт свой уникальный id.
https://github.com/reactwg/react-18/discussions/111
В React 18 появится новый хук для генерации уникальных id. Этот хук можно использовать для связки названия и инпута:
function Checkbox() {
const id = useId();
return (
<>
<label htmlFor={id}>Do you like React?</label>
<input type="checkbox" name="react" id={id} />
</>
);
);
Проблема, которую решает хук useId, связана с новым подходом серверного рендеринга в React. Раньше для генерации уникальных id использовался простой счетчик. В новой версии React, при использовании конкурентного рендеринга, HTML может передаваться в произвольном порядке.
Для генерации уникальных id в хуке useId используется текущая позиция компонента в дереве приложения. Внутри React, id представляет из себя двоичное число. Для дочерних элементов добавляются дополнительные биты слева от последовательности родителя, которые представляет положение дочернего элемента на текущем уровне дочерних элементов.
00101 00010001011010101
╰──┬──╯ ╰────────┬────────╯
Fork 5 of 20 id родителя
Это позволяет быть уверенным, что каждый вызов useId будет возвращать уникальный id. Если в компоненте несколько лейблов и инпутов, то можно добавить локальные префиксы, что гарантирует уникальность id глобально:
function NameFields() {
const id = useId();
return (
<div>
<label htmlFor={id + '-firstName'}>First Name</label>
<div>
<input id={id + '-firstName'} type="text" />
</div>
<label htmlFor={id + '-lastName'}>Last Name</label>
<div>
<input id={id + '-lastName'} type="text" />
</div>
</div>
);
}
Хотя так делать не обязательно, если несколько раз вызвать useId в одном компоненте, то каждый из них вернёт свой уникальный id.
https://github.com/reactwg/react-18/discussions/111
GitHub
Intent to Ship: useId · reactwg/react-18 · Discussion #111
This feature is now available in the latest alphas facebook/react#22644 useId is an API for generating unique IDs on both the client and server, while avoiding hydration mismatches. We haven't ...
Как работает React
Rodrigo Pombo рассказывает о том, как работает React внутри: что такое фибер, как работает конкурентный режим, каким образом изменение хука вызывает ререндер компонента.
Также есть статья на хабре на русском.
https://pomb.us/build-your-own-react/
Rodrigo Pombo рассказывает о том, как работает React внутри: что такое фибер, как работает конкурентный режим, каким образом изменение хука вызывает ререндер компонента.
Также есть статья на хабре на русском.
https://pomb.us/build-your-own-react/
Хабр
Как работает React: подробное руководство
Привет, друзья! В этой статье я покажу вам, с чего начинается React . Что это означает? Это означает, что мы разработаем мини-версию React , которая сможет выполнять следующий код: import...
This media is not supported in your browser
VIEW IN TELEGRAM
Расширение VS Code для просмотра компонентов
Sapling – это расширение для просмотра иерархии компонентов проекта в сайдбаре VS Code.
Каждый узел в такой иерархии – компонент React. У каждого узла есть несколько иконок:
- Список пропсов, которые отображаются при наведении.
- Переход в файл компонента.
- Индикатор подключения к Redux.
Текущий открытый узел в дереве выделяется жирным. Также, если в файле с компонентом есть ошибка, например неправильный импорт, то соответствующий узел в иерархии выделяется ошибкой.
Для работы расширения используется
https://marketplace.visualstudio.com/items?itemName=team-sapling.sapling
Sapling – это расширение для просмотра иерархии компонентов проекта в сайдбаре VS Code.
Каждый узел в такой иерархии – компонент React. У каждого узла есть несколько иконок:
- Список пропсов, которые отображаются при наведении.
- Переход в файл компонента.
- Индикатор подключения к Redux.
Текущий открытый узел в дереве выделяется жирным. Также, если в файле с компонентом есть ошибка, например неправильный импорт, то соответствующий узел в иерархии выделяется ошибкой.
Для работы расширения используется
@babel/parser для создания AST и VS Code Extension API для интеграции в VS Code. Для отображения используется React. https://marketplace.visualstudio.com/items?itemName=team-sapling.sapling
Конференция React Conf 2021
В этом году конференция Reacf Conf пройдет онлайн 8 декабря, регистрация бесплатная.
Будет 20 спикеров, среди которых есть ребята из команды React, например, Andrew Clark, один из разработчиков хуков, Suspense и конкурентного режима. Также есть ребята из Microsoft, Paypal, Netflix.
Темы докладов пока неизвестны, но думаю, одна из тем будет про новый React 18.
https://conf.reactjs.org/
В этом году конференция Reacf Conf пройдет онлайн 8 декабря, регистрация бесплатная.
Будет 20 спикеров, среди которых есть ребята из команды React, например, Andrew Clark, один из разработчиков хуков, Suspense и конкурентного режима. Также есть ребята из Microsoft, Paypal, Netflix.
Темы докладов пока неизвестны, но думаю, одна из тем будет про новый React 18.
https://conf.reactjs.org/
conf.reactjs.org
React Conf 2021
useEffect – основные проблемы и способы их решения
В статье, в процессе создания кастомного хука, разбираются возможные проблемы при работе с хуком useEffect.
Одна из возможных проблем – хук useEffect вызывается при каждом рендере компонента. Если в хуке устанавливается состояние, то это может привести к бесконечному ререндеру приложения. Возможная причина такого поведения useEffect связана либо с отсутствием аргумента зависимостей, либо зависимость меняется в каждом рендере.
Если в качестве зависимости у хука useEffect используется объект, объявленный внутри компонента, то ссылка на этот объект меняется в каждом рендере. Поэтому нужно использовать useMemo для объявления объектов внутри компонента, если они в дальнейшем будут передаваться в useEffect.
https://www.freecodecamp.org/news/most-common-react-useeffect-problems-and-how-to-fix-them/
В статье, в процессе создания кастомного хука, разбираются возможные проблемы при работе с хуком useEffect.
Одна из возможных проблем – хук useEffect вызывается при каждом рендере компонента. Если в хуке устанавливается состояние, то это может привести к бесконечному ререндеру приложения. Возможная причина такого поведения useEffect связана либо с отсутствием аргумента зависимостей, либо зависимость меняется в каждом рендере.
Если в качестве зависимости у хука useEffect используется объект, объявленный внутри компонента, то ссылка на этот объект меняется в каждом рендере. Поэтому нужно использовать useMemo для объявления объектов внутри компонента, если они в дальнейшем будут передаваться в useEffect.
https://www.freecodecamp.org/news/most-common-react-useeffect-problems-and-how-to-fix-them/
freeCodeCamp.org
React.useEffect Hook – Common Problems and How to Fix Them
By Iva Kop React hooks have been around for a while now. Most developers have gotten pretty comfortable with how they work and their common use cases. But there is one useEffect gotcha that a lot of us keep falling for. The use case Let's start with ...
Предотвращаем рендеры компонента с react-freeze
Ребята из Software Mansion представили библиотеку react-freeze.
React-freeze позволяет “замораживать” рендер компонента, используя механизм Suspense, представленный в React 17. Основная цель библиотеки заключается в предотвращении лишних рендеров. При “заморозке” компонент не размонтируется, внутреннее состояние компонента и его дерево сохраняются, а сам компонент заменяется на плейсхолдер.
Например, библиотеку можно использовать в таких элементах как табы. Когда таб скрыт, то его компонент можно “заморозить”, чтобы не тратить время на его рендер.
Библиотека использует механизм работы Suspense. Компонент оборачивается в Suspense и обертку Suspender. Когда нужно “заморозить” компонент, то в Suspender выбрасывается исключение Promise , который перехватывает Suspense. При получении промиса-исключения, Suspense ставит компонент в режим ожидания, предотвращая лишний рендер и изменение состояния.
Github https://github.com/software-mansion-labs/react-freeze
Статья https://blog.swmansion.com/experimenting-with-react-freeze-71da578e2fa6
Ребята из Software Mansion представили библиотеку react-freeze.
React-freeze позволяет “замораживать” рендер компонента, используя механизм Suspense, представленный в React 17. Основная цель библиотеки заключается в предотвращении лишних рендеров. При “заморозке” компонент не размонтируется, внутреннее состояние компонента и его дерево сохраняются, а сам компонент заменяется на плейсхолдер.
Например, библиотеку можно использовать в таких элементах как табы. Когда таб скрыт, то его компонент можно “заморозить”, чтобы не тратить время на его рендер.
Библиотека использует механизм работы Suspense. Компонент оборачивается в Suspense и обертку Suspender. Когда нужно “заморозить” компонент, то в Suspender выбрасывается исключение Promise , который перехватывает Suspense. При получении промиса-исключения, Suspense ставит компонент в режим ожидания, предотвращая лишний рендер и изменение состояния.
Github https://github.com/software-mansion-labs/react-freeze
Статья https://blog.swmansion.com/experimenting-with-react-freeze-71da578e2fa6
GitHub
GitHub - software-mansion/react-freeze: Prevent React component subtrees from rendering.
Prevent React component subtrees from rendering. Contribute to software-mansion/react-freeze development by creating an account on GitHub.