Антипаттерны 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.
Избегаем состояния гонки в React
Состояние гонки описывает ситуацию, когда поведение системы зависит от определенной последовательности событий, но их порядок неуправляем. Одним из примеров является многопоточность, когда несколько потоков пытаются изменить общие данные. Аналогичная проблема может возникнуть с асинхронностью в JavaScript.
Состояние гонки в приложениях React можно воспроизвести на примере с получением данных в useEffect. Например, при изменении зависимостей deps у useEffect запрос fetch начнет выполняться и при его успехе произойдет изменение стейта. Однако, если не отменить старый запрос fetch, то может произойти коллизия: два события пытаются изменить общие данные.
Также, если компонент будет размонтирован и после выполнения запроса fetch произойдет изменение стейта, то будет ошибка React:
Чтобы избежать подобных ситуаций, необходимо отменять запрос fetch, если он больше не нужен. Один из вариантов – использовать guard переменную, которая будет определять актуальность запроса. Другой вариант – использовать AbortController в fetch.
https://academind.com/tutorials/useeffect-abort-http-requests
Состояние гонки описывает ситуацию, когда поведение системы зависит от определенной последовательности событий, но их порядок неуправляем. Одним из примеров является многопоточность, когда несколько потоков пытаются изменить общие данные. Аналогичная проблема может возникнуть с асинхронностью в JavaScript.
Состояние гонки в приложениях React можно воспроизвести на примере с получением данных в useEffect. Например, при изменении зависимостей deps у useEffect запрос fetch начнет выполняться и при его успехе произойдет изменение стейта. Однако, если не отменить старый запрос fetch, то может произойти коллизия: два события пытаются изменить общие данные.
Также, если компонент будет размонтирован и после выполнения запроса fetch произойдет изменение стейта, то будет ошибка React:
Warning: Can't perform a React state update on an unmounted component.Чтобы избежать подобных ситуаций, необходимо отменять запрос fetch, если он больше не нужен. Один из вариантов – использовать guard переменную, которая будет определять актуальность запроса. Другой вариант – использовать AbortController в fetch.
https://academind.com/tutorials/useeffect-abort-http-requests
Academind
useEffect(), Http Requests & Aborting
Sending a Http request with useEffect() might be trickier than you think - or did you consider aborting requests and avoiding race conditions?
React 18 перешел в статус beta
В период с версии alpha были добавлены следующие фичи в будущий релиз:
- useSyncExternalStore
- useId (обзор)
- useInsertionEffect
По сообщению Andrew Clark, в React 18 больше не будет новых API. Оставшаяся работа заключается в разработке документации и различных улучшениях, например, сообщения об ошибках.
https://github.com/reactwg/react-18/discussions/112
В период с версии alpha были добавлены следующие фичи в будущий релиз:
- useSyncExternalStore
- useId (обзор)
- useInsertionEffect
По сообщению Andrew Clark, в React 18 больше не будет новых API. Оставшаяся работа заключается в разработке документации и различных улучшениях, например, сообщения об ошибках.
https://github.com/reactwg/react-18/discussions/112
GitHub
useMutableSource → useSyncExternalStore · reactwg react-18 · Discussion #86
Since experimental useMutableSource API was added, we’ve made changes to our overall concurrent rendering model that have led us to reconsider its design. Members of this Working Group have also re...
Техническое погружение в react-three-fiber
Коди Беннетт пишет о технической реализации кастомного React рендерера react-three-fiber.
В статье описан принцип работы кастомного рендерера, а также как реализован HostConfig реконсайлера для Three.js.
Перед прочтением рекомендую ознакомиться с заметкой про устройство кастомных React рендереров – https://news.1rj.ru/str/ru_react_notes/29.
https://codyb.co/articles/a-technical-breakdown-of-react-three-fiber
Коди Беннетт пишет о технической реализации кастомного React рендерера react-three-fiber.
В статье описан принцип работы кастомного рендерера, а также как реализован HostConfig реконсайлера для Three.js.
Перед прочтением рекомендую ознакомиться с заметкой про устройство кастомных React рендереров – https://news.1rj.ru/str/ru_react_notes/29.
https://codyb.co/articles/a-technical-breakdown-of-react-three-fiber
Гайд по разработке React приложений
Bulletproof React – репозиторий-пример, в котором собраны различные библиотеки и инструменты, которые покрывают большинство аспектов разработки приложения на React. В репозитории есть статьи про настройку проекта, тестирование, стейт менеджеры, перфоманс и т.д.
Автор проекта не предлагает использовать репозиторий как шаблон для проектов. Цель проекта показать, как можно решать основные проблемы, возникающие в разработке приложения на React.
https://github.com/alan2207/bulletproof-react
Bulletproof React – репозиторий-пример, в котором собраны различные библиотеки и инструменты, которые покрывают большинство аспектов разработки приложения на React. В репозитории есть статьи про настройку проекта, тестирование, стейт менеджеры, перфоманс и т.д.
Автор проекта не предлагает использовать репозиторий как шаблон для проектов. Цель проекта показать, как можно решать основные проблемы, возникающие в разработке приложения на React.
https://github.com/alan2207/bulletproof-react
GitHub
GitHub - alan2207/bulletproof-react: 🛡️ ⚛️ A simple, scalable, and powerful architecture for building production ready React applications.
🛡️ ⚛️ A simple, scalable, and powerful architecture for building production ready React applications. - GitHub - alan2207/bulletproof-react: 🛡️ ⚛️ A simple, scalable, and powerful architecture for...
Причины вызова useEffect перед отрисовкой
Владимир Клепов разбирается с причинами запуска useEffect перед этапом отрисовки браузера. Причиной такого поведения может стать изменение стейта в useLayoutEffect.
В документации React написано, что useEffect вызывается после этапа отрисовки браузера. Чаще всего это так, и это оптимальный случай.
Изменение стейта в useLayoutEffect провоцирует новый ререндер. Перед новым ререндером происходит вызов оставшихся / ожидающих вызова useEffect. Дальше происходит стандартный флоу: обновление, вызов useLayoutEffect, отрисовка и вызов useEffect.
https://thoughtspile.github.io/2021/11/15/unintentional-layout-effect/
Владимир Клепов разбирается с причинами запуска useEffect перед этапом отрисовки браузера. Причиной такого поведения может стать изменение стейта в useLayoutEffect.
В документации React написано, что useEffect вызывается после этапа отрисовки браузера. Чаще всего это так, и это оптимальный случай.
Изменение стейта в useLayoutEffect провоцирует новый ререндер. Перед новым ререндером происходит вызов оставшихся / ожидающих вызова useEffect. Дальше происходит стандартный флоу: обновление, вызов useLayoutEffect, отрисовка и вызов useEffect.
https://thoughtspile.github.io/2021/11/15/unintentional-layout-effect/
Vladimir Klepov as a Coder
useEffect sometimes fires before paint
React стейты с фрагментированным стором
Teaful – крошечная библиотека для управления состоянием приложения. Её особенность заключается в фрагментированном сторе, который позволяет избежать повторного рендеринга компонентов. С помощью Teaful каждое поле стора можно использовать отдельно, поэтому при обновлении других полей стора, которые не используются, компонент не будет рендерится заново.
Под капотом Teaful использует контексты. Для каждого поля стора создается отдельный провайдер и хук-потребитель.
🇬🇧 https://dev.to/aralroca/react-state-with-a-fragmented-store-18ff
🇷🇺 https://habr.com/ru/company/skillfactory/blog/591605/
https://github.com/teafuljs/teaful
Teaful – крошечная библиотека для управления состоянием приложения. Её особенность заключается в фрагментированном сторе, который позволяет избежать повторного рендеринга компонентов. С помощью Teaful каждое поле стора можно использовать отдельно, поэтому при обновлении других полей стора, которые не используются, компонент не будет рендерится заново.
Под капотом Teaful использует контексты. Для каждого поля стора создается отдельный провайдер и хук-потребитель.
🇬🇧 https://dev.to/aralroca/react-state-with-a-fragmented-store-18ff
🇷🇺 https://habr.com/ru/company/skillfactory/blog/591605/
https://github.com/teafuljs/teaful
DEV Community
React state with a fragmented store
Fragmented store concept and how to apply it with React Context
Вышел React Router v6
В React Router v6 добавлены новые фичи, улучшена поддержка с последними версиями React. Также новая версия содержит несколько критических изменений по сравнению с пятой версией. В React Router v6 активно используются хуки, поэтому для работы требуется версия React 16.8 и выше.
- Вместо <Switch> используйте <Routes>. Внутри <Routes> все роуты и ссылки <Link to> будут относительными. Этот подход упростит работу с вложенными роутами, не нужно будет использовать match.url.
- Используется элемент вместо компонента в роутах <Route>. Для рендера можно передать любой элемент в проп element. Вложенные роуты задаются в children.
- Добавлен компонент <Outlet>. Позволяет отображать вложенный UI при рендере дочерних роутов. Также в <Route> добавлен проп index, который работает в связке с <Outlet>. Если родительский роут соответствует текущему URL браузера, то будет отрендерен <Route index>, если он есть среди дочерних роутов.
- Изменения в <Route path>. Были оставлены только два типа плейсхолдера:
- Изменилось поведение <Link to>. Если путь в to не начинается с /, то он будет рендерить ссылку, относительную роуту, в котором был отрендерен. Использование в <Link to>
- Добавлены новые хуки. Если храните роуты в виде объекта и используете react-router-config, то в v6 есть хук useRoutes для рендера роутов в виде объекта.
Вместо useHistory используйте useNavigate. Чаще всего будет достаточно переименовать название хука и изменить вызовы history.push или history.replace на navigate. Хук useNavigate полезен тем, что поддерживает React Suspense. Например, если был переход с роута, который еще не был загружен, то происходит замена URL, а не пуш в историю браузера.
https://reactrouter.com/docs/en/v6/upgrading/v5
В React Router v6 добавлены новые фичи, улучшена поддержка с последними версиями React. Также новая версия содержит несколько критических изменений по сравнению с пятой версией. В React Router v6 активно используются хуки, поэтому для работы требуется версия React 16.8 и выше.
- Вместо <Switch> используйте <Routes>. Внутри <Routes> все роуты и ссылки <Link to> будут относительными. Этот подход упростит работу с вложенными роутами, не нужно будет использовать match.url.
- Используется элемент вместо компонента в роутах <Route>. Для рендера можно передать любой элемент в проп element. Вложенные роуты задаются в children.
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="users" element={<Users />}>
<Route path="me" element={<OwnUserProfile />} />
<Route path=":id" element={<UserProfile />} />
</Route>
</Routes>
</BrowserRouter>
);
}
function Users() {
return (
<div>
<nav>
<Link to="me">My Profile</Link>
</nav>
<Outlet />
</div>
);
}
- Добавлен компонент <Outlet>. Позволяет отображать вложенный UI при рендере дочерних роутов. Также в <Route> добавлен проп index, который работает в связке с <Outlet>. Если родительский роут соответствует текущему URL браузера, то будет отрендерен <Route index>, если он есть среди дочерних роутов.
- Изменения в <Route path>. Были оставлены только два типа плейсхолдера:
:id и * в конце пути. Была удалена поддержка RegExp в пути. Чувствительность к регистру пути переехала в <Routes caseSensitive>. - Изменилось поведение <Link to>. Если путь в to не начинается с /, то он будет рендерить ссылку, относительную роуту, в котором был отрендерен. Использование в <Link to>
.. удаляет сегмент родительского роута, а не URL.
<Routes>
<Route path="users">
<Route
path=":id/messages"
element={
// Ссылка ведет в /users
<Link to=".." />
}
/>
</Route>
</Routes>
- Добавлены новые хуки. Если храните роуты в виде объекта и используете react-router-config, то в v6 есть хук useRoutes для рендера роутов в виде объекта.
Вместо useHistory используйте useNavigate. Чаще всего будет достаточно переименовать название хука и изменить вызовы history.push или history.replace на navigate. Хук useNavigate полезен тем, что поддерживает React Suspense. Например, если был переход с роута, который еще не был загружен, то происходит замена URL, а не пуш в историю браузера.
https://reactrouter.com/docs/en/v6/upgrading/v5
Reactrouter
Upgrading from v5 v6.30.1
Фасад при использовании UI библиотеки
Кайл Шевлин делится архитектурным приемом при использовании сторонних UI библиотек: для каждого UI компонента из библиотеки создать компонент-фасад и использовать его в проекте. Например:
Само собой, такой вариант использования UI библиотеки не подходит всем проектам. Иногда, в больших и долгоживущих проектах, бывают изменения в дизайне UI компонента. В этом случае, вариант с использованием фасада облегчает работу над этими изменениями, сведя все изменения в одном компоненте.
При использовании фасада также можно:
- Легко изменить UI библиотеку. Так как привязка к UI библиотеке только в определенных компонентах, то сделать это гораздо проще, чем без использования фасада.
- Добавить или ограничить пропсы UI компонентов.
- Переименовать или переназначить пропсы UI компонентов.
https://kyleshevlin.com/how-I-would-use-a-ui-library
Кайл Шевлин делится архитектурным приемом при использовании сторонних UI библиотек: для каждого UI компонента из библиотеки создать компонент-фасад и использовать его в проекте. Например:
import React from 'react'
import { Button as ChakraButton } from '@chakra-ui/react'
export default function Button(props) {
return <ChakraButton {...props} />
}
Само собой, такой вариант использования UI библиотеки не подходит всем проектам. Иногда, в больших и долгоживущих проектах, бывают изменения в дизайне UI компонента. В этом случае, вариант с использованием фасада облегчает работу над этими изменениями, сведя все изменения в одном компоненте.
При использовании фасада также можно:
- Легко изменить UI библиотеку. Так как привязка к UI библиотеке только в определенных компонентах, то сделать это гораздо проще, чем без использования фасада.
- Добавить или ограничить пропсы UI компонентов.
- Переименовать или переназначить пропсы UI компонентов.
https://kyleshevlin.com/how-I-would-use-a-ui-library
Kyle Shevlin's Blog
How I Would Use a UI Library | Kyle Shevlin
UI Libraries are great for having a solid design system to build from. Here's a small architectural decision I would do to make them even nicer to work with.
Краткое знакомство с Elm для React разработчиков
Elm – это язык, разработанный для создания интерфейсов приложения, предлагающий альтернативу JS библиотекам, таким как React.
Под капотом Elm, как и в React, используется виртуальный DOM, а также оба используют декларативный стиль для описания UI. Основное отличие между ними в том, что React – это JavaScript библиотека, а Elm – функциональный язык, разработанный с нуля для декларативного создания веб-интерфейсов.
Одной из особенностей Elm является мощная типизация, которая позволяет отловить и предупредить о граничных случаях. В результате строгой типизации, при работе приложения практически отсутствуют ошибки в рантайме.
Пример счетчика на Elm:
https://blog.theodo.com/2021/10/intro-to-elm-for-react-devs/
Elm – это язык, разработанный для создания интерфейсов приложения, предлагающий альтернативу JS библиотекам, таким как React.
Под капотом Elm, как и в React, используется виртуальный DOM, а также оба используют декларативный стиль для описания UI. Основное отличие между ними в том, что React – это JavaScript библиотека, а Elm – функциональный язык, разработанный с нуля для декларативного создания веб-интерфейсов.
Одной из особенностей Elm является мощная типизация, которая позволяет отловить и предупредить о граничных случаях. В результате строгой типизации, при работе приложения практически отсутствуют ошибки в рантайме.
Пример счетчика на Elm:
type Msg = Increment | Decrement
init = { count = 0 }
update msg model =
case msg of
Increment -> { model | count = model.count + 1 }
Decrement -> { model | count = model.count - 1 }
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, text (String.fromInt model.count)
, button [ onClick Increment ] [ text "+" ]
]
https://blog.theodo.com/2021/10/intro-to-elm-for-react-devs/
Theodo
A Quick Intro to Elm for React Developers | Theodo
An introduction to the Elm functional programming language for frontend web developers familiar with React, JavaScript and TypeScript
Как заменить useState на useRef и выиграть в производительности
Основной способ вызвать ререндер компонентов в React заключается в изменении стейта. Использование стейта в компонентах – это безопасный вариант работы с динамическими значениями: мы всегда будем уверены, что при изменении стейта произойдет ререндер компонента.
Не всегда использование стейта целесообразно, бывают случаи, когда от него можно отказаться. Правда, иногда при отказе от стейта, можно выстрелить себе в ногу, но если сделать все правильно, то можно увеличить производительность приложения.
Стейт обязательно нужно использовать в двух случаях: когда стейт влияет на DOM, участвуя в рендере компонента, и когда необходимо вызывать эффект useEffect.
Ситуации, когда стейт можно не использовать:
- Если значения нужны только в коллбэках, то используйте рефы.
- Буферизация изменений стейта. Если колбек вызывается слишком часто и в нем происходит изменение стейта, то возможно будет эффективнее запланировать изменение стейта используя requestAnimationFrame.
- Императивное изменение DOM узла. Например, если реализуется анимация, то гораздо эффективнее напрямую изменять стили DOM узла. Если для анимации использовать стейт, то потребуется очень много ререндеров компонента, что повлияет на производительность.
https://thoughtspile.github.io/2021/10/18/non-react-state/
Основной способ вызвать ререндер компонентов в React заключается в изменении стейта. Использование стейта в компонентах – это безопасный вариант работы с динамическими значениями: мы всегда будем уверены, что при изменении стейта произойдет ререндер компонента.
Не всегда использование стейта целесообразно, бывают случаи, когда от него можно отказаться. Правда, иногда при отказе от стейта, можно выстрелить себе в ногу, но если сделать все правильно, то можно увеличить производительность приложения.
Стейт обязательно нужно использовать в двух случаях: когда стейт влияет на DOM, участвуя в рендере компонента, и когда необходимо вызывать эффект useEffect.
Ситуации, когда стейт можно не использовать:
- Если значения нужны только в коллбэках, то используйте рефы.
- Буферизация изменений стейта. Если колбек вызывается слишком часто и в нем происходит изменение стейта, то возможно будет эффективнее запланировать изменение стейта используя requestAnimationFrame.
- Императивное изменение DOM узла. Например, если реализуется анимация, то гораздо эффективнее напрямую изменять стили DOM узла. Если для анимации использовать стейт, то потребуется очень много ререндеров компонента, что повлияет на производительность.
https://thoughtspile.github.io/2021/10/18/non-react-state/
Vladimir Klepov as a Coder
How to replace useState with useRef and be a winner
This media is not supported in your browser
VIEW IN TELEGRAM
Расширение для отладки React приложений – Reactime
Инструмент позволяет отследить количество рендеров компонента и среднее время рендера. Киллер-фичей расширения является возможность переключения текущего состояния приложения – time-traveling, как в Redux DevTools.
Принцип работы расширения заключается в обходе дерева React Fiber и в сборе информации о рендере компонента. Reactime сохраняет каждый снапшот рендера компонента, включая стейт и время рендера, после чего строит граф компонентов. Расширение умеет сохранять стейт как у классовых компонентов, так и у функциональных, которые используют хуки.
Для работы расширения не требуется каких-то изменений в коде проекта, достаточно запустить его в браузере и иметь уже предустановленный React DevTools.
https://chrome.google.com/webstore/detail/reactime/cgibknllccemdnfhfpmjhffpjfeidjga?hl=en-US
🇺🇸 https://medium.com/@liuedar/what-time-is-it-reactime-fd7267b9eb89
Инструмент позволяет отследить количество рендеров компонента и среднее время рендера. Киллер-фичей расширения является возможность переключения текущего состояния приложения – time-traveling, как в Redux DevTools.
Принцип работы расширения заключается в обходе дерева React Fiber и в сборе информации о рендере компонента. Reactime сохраняет каждый снапшот рендера компонента, включая стейт и время рендера, после чего строит граф компонентов. Расширение умеет сохранять стейт как у классовых компонентов, так и у функциональных, которые используют хуки.
Для работы расширения не требуется каких-то изменений в коде проекта, достаточно запустить его в браузере и иметь уже предустановленный React DevTools.
https://chrome.google.com/webstore/detail/reactime/cgibknllccemdnfhfpmjhffpjfeidjga?hl=en-US
🇺🇸 https://medium.com/@liuedar/what-time-is-it-reactime-fd7267b9eb89
🔥1
Конференция React Conf 2021
Уже сегодня пройдет очередная ежегодная конференция React Conf 2021. Будет очень много тем про React 18.
Начало в 21:00 по Москве. Расписание докладов:
🗓️ 8 декабря 2021 г., 21:00 React 18 Keynote (Andrew Clark, Lauren Tan, Juan Tejada, Ricky Hanlon)
🗓️ 21:34 React 18 for app developers (Shruti Kapoor)
🗓️ 21:53 Streaming Server Rendering with Suspense (Shaundai Person)
🗓️ 22:12 The first React Working Group (Aakansha Doshi)
🗓️ 22:27 React Developer Tooling (Brian Vaughn)
🗓️ 22:27 React without memo (Xuan Huang)
🗓️ 23:00 React Docs Keynote (Rachel Nabors)
🗓️ 23:11 Things I learnt from the new React docs (Debbie O'Brien)
🗓️ 23:20 Learning in the Browser (Sarah Rainsberger)
🗓️ 23:31 The ROI of Designing with React (Linton Ye)
🗓️ 23:42 Interactive playgrounds with React (Delba de Oliveira)
🗓️ 9 декабря 2021 г., 0:00 Re-introducing Relay (Robert Balicki)
🗓️ 00:20 React Native Desktop (Eric Rozell, Steven Moyes)
🗓️ 00:36 On-device Machine Learning for React Native (Roman Rädle)
🗓️ 01:00 React 18 for External Store Libraries (Daishi Kato)
🗓️ 01:20 Building accessible components with React 18 (Diego Haz)
🗓️ 01:29 Accessible Japanese Form Components with React (Tafu Nakazaki)
🗓️ 01:39 UI Tools for Artists (Lyle Troxell)
🗓️ 01:49 Hydrogen + React 18 (Helen Lin)
https://conf.reactjs.org/
https://discord.gg/reactconf
Уже сегодня пройдет очередная ежегодная конференция React Conf 2021. Будет очень много тем про React 18.
Начало в 21:00 по Москве. Расписание докладов:
🗓️ 8 декабря 2021 г., 21:00 React 18 Keynote (Andrew Clark, Lauren Tan, Juan Tejada, Ricky Hanlon)
🗓️ 21:34 React 18 for app developers (Shruti Kapoor)
🗓️ 21:53 Streaming Server Rendering with Suspense (Shaundai Person)
🗓️ 22:12 The first React Working Group (Aakansha Doshi)
🗓️ 22:27 React Developer Tooling (Brian Vaughn)
🗓️ 22:27 React without memo (Xuan Huang)
🗓️ 23:00 React Docs Keynote (Rachel Nabors)
🗓️ 23:11 Things I learnt from the new React docs (Debbie O'Brien)
🗓️ 23:20 Learning in the Browser (Sarah Rainsberger)
🗓️ 23:31 The ROI of Designing with React (Linton Ye)
🗓️ 23:42 Interactive playgrounds with React (Delba de Oliveira)
🗓️ 9 декабря 2021 г., 0:00 Re-introducing Relay (Robert Balicki)
🗓️ 00:20 React Native Desktop (Eric Rozell, Steven Moyes)
🗓️ 00:36 On-device Machine Learning for React Native (Roman Rädle)
🗓️ 01:00 React 18 for External Store Libraries (Daishi Kato)
🗓️ 01:20 Building accessible components with React 18 (Diego Haz)
🗓️ 01:29 Accessible Japanese Form Components with React (Tafu Nakazaki)
🗓️ 01:39 UI Tools for Artists (Lyle Troxell)
🗓️ 01:49 Hydrogen + React 18 (Helen Lin)
https://conf.reactjs.org/
https://discord.gg/reactconf
conf.reactjs.org
React Conf 2021
Паттерн загрузки данных с Toast & SWR
Теодор Кларенс в своем блоге описывает подход к загрузке данных через кастомный хук и использование нотификаций.
При загрузке данных необходимо отображать пользователю текущий статус загрузки. Это может быть индикатор загрузки, сообщение об ошибке или сообщение об успешной загрузки. Также, если отправляется форма, то необходимо задизейблить кнопку отправки, чтобы форма не отправлялась больше одного раза. Для работы описанного поведения в крайнем случае необходимо заводить как минимум 3 стейта. Для переиспользования логики можно создать кастомный хук.
Теодор Кларенс использовал react-hot-toast для отображения текущего статуса загрузки в виде нотификаций. Библиотека react-hot-toast умеет принимать промис и отображать сообщение в зависимости от состояния промиса. Для получения данных используется библиотека swr, которая умеет кэшировать ответы на запросы и обновлять кэш при повторном обращении.
https://theodorusclarence.com/blog/react-loading-state-pattern
Теодор Кларенс в своем блоге описывает подход к загрузке данных через кастомный хук и использование нотификаций.
При загрузке данных необходимо отображать пользователю текущий статус загрузки. Это может быть индикатор загрузки, сообщение об ошибке или сообщение об успешной загрузки. Также, если отправляется форма, то необходимо задизейблить кнопку отправки, чтобы форма не отправлялась больше одного раза. Для работы описанного поведения в крайнем случае необходимо заводить как минимум 3 стейта. Для переиспользования логики можно создать кастомный хук.
Теодор Кларенс использовал react-hot-toast для отображения текущего статуса загрузки в виде нотификаций. Библиотека react-hot-toast умеет принимать промис и отображать сообщение в зависимости от состояния промиса. Для получения данных используется библиотека swr, которая умеет кэшировать ответы на запросы и обновлять кэш при повторном обращении.
const { data: pokemonData, isLoading } = useWithToast(
useSWR<PokemonList>('https://pokeapi.co/api/v2/pokemon?limit=20')
);
https://theodorusclarence.com/blog/react-loading-state-pattern
React-Hot-Toast
react-hot-toast - The Best React Notifications in Town - react-hot-toast
Add beautiful notifications to your React app with react-hot-toast. Lightweight. Smoking hot by default.
Почему стоит обратить внимание на Remix
Remix – это новый фулстек фреймворк на React. Фреймворк из коробки поддерживает технологию прогрессивного улучшения, что гарантирует работу практически во всех браузерах.
При разработке на Remix необходимо соблюдать определенные условности, начиная от структуры проекта и наименования файлов до экспортов внутри модуля.
Каждый модуль экспортирует API, которое будет использовать Remix при компиляции проекта. Экспортируемая переменная loader определяет функцию, которая будет вызываться на сервере перед рендерингом компонента, чтобы подготовить данные. Получить эти данные в компоненте можно через хук
Remix состоит из компилятора, серверного HTTP обработчика, серверного фреймворка и браузерного фреймворка. С помощью компилятора каждый модуль превращается в браузерный бандл и в бандл для серверного HTTP обработчика. Серверные HTTP обработчики позволяют запускать сервер как на Node.js серверах, так и на serverless серверах, например, Cloudflare Workers. Серверный фреймворк позволяет для каждого роута добавить функцию подготовки данных loader и функцию обработки формы action. Браузерный фреймворк позволяет работать приложению как SPA, дает возможность использовать хуки для взаимодействия с сервером, а также предзагружает ресурсы для страниц сайта.
Пример Remix модуля:
https://remix.run/docs/en/v1
🇺🇸 https://blog.plasmic.app/posts/why-remix-is-worth-your-attention/
Remix – это новый фулстек фреймворк на React. Фреймворк из коробки поддерживает технологию прогрессивного улучшения, что гарантирует работу практически во всех браузерах.
При разработке на Remix необходимо соблюдать определенные условности, начиная от структуры проекта и наименования файлов до экспортов внутри модуля.
Каждый модуль экспортирует API, которое будет использовать Remix при компиляции проекта. Экспортируемая переменная loader определяет функцию, которая будет вызываться на сервере перед рендерингом компонента, чтобы подготовить данные. Получить эти данные в компоненте можно через хук
useLoaderData. Основной способ передачи информации с клиента на сервер – формы. Для обработки форм в модуле экспортируется переменная action. Внутри функции action можно валидировать поля, обращаться к базе данных и возвращать ответ. Ответ на стороне клиента можно получить через хук useActionData, в котором, например, могут приходить ошибки валидации. Экспорт default – это сам компонент. Remix состоит из компилятора, серверного HTTP обработчика, серверного фреймворка и браузерного фреймворка. С помощью компилятора каждый модуль превращается в браузерный бандл и в бандл для серверного HTTP обработчика. Серверные HTTP обработчики позволяют запускать сервер как на Node.js серверах, так и на serverless серверах, например, Cloudflare Workers. Серверный фреймворк позволяет для каждого роута добавить функцию подготовки данных loader и функцию обработки формы action. Браузерный фреймворк позволяет работать приложению как SPA, дает возможность использовать хуки для взаимодействия с сервером, а также предзагружает ресурсы для страниц сайта.
Пример Remix модуля:
// routes/todos.js
import { redirect, Form } from "remix";
export async function loader() {
return fakeGetTodos();
}
export async function action({ request }) {
const body = await request.formData();
const todo = await fakeCreateTodo({
noscript: body.get("noscript")
});
return redirect(`/todos/${todo.id}`);
}
export default function Todos() {
const data = useLoaderData();
return (
<div>
<TodoList todos={data} />
<Form method="post">
<input type="text" name="noscript" />
<button type="submit">Create Todo</button>
</Form>
</div>
);
}
https://remix.run/docs/en/v1
🇺🇸 https://blog.plasmic.app/posts/why-remix-is-worth-your-attention/
Remix
Remix Docs Home (v1.19.3) | Remix