Пример использования startTransition и 3D-рендеринга
В React 18 был добавлен конкурентный рендеринг. Основная его идея в том, что обновления стейта можно разделить на две категории:
- Срочные обновления: обеспечивают оперативный отклик на пользовательские события, например, ввод текста или скролл.
- Переходные обновления: представляют несрочные задачи для рендера UI, например, отображение датасета.
Цель переходных обновлений состоит в том, чтобы создать более отзывчивый интерфейс.
До React 18 все обновления стейта считались срочными и ввод текста или клик могли зафризить UI при рендере тяжелого компонента. В React 18 с помощью переходных обновлений рендер тяжелых компонентов будет происходить в фоне, в то время как UI будет оставаться отзывчивым.
Конкурентный рендеринг может выполнять следующие вещи:
- Yielding: React периодически ставит работу рендера на паузу, чтобы дать браузеру сделать другую работу.
- Прерывание: при появлении срочных задач React ставит рендер несрочной задачи на паузу и начинает рендерить срочную задачу, чтобы UI оставался отзывчивым.
- Отбрасывание старых результатов: если данные стейта для перехода устарели, то React отбрасывает старый рендер и начинает рендер по новой для свежего стейта.
Доу-Чи Лиу в своем блоге показал, как использовать API конкурентного рендеринга startTransition для рендера тяжелого компонента с 3D моделью с визуализацией связей между пользователями в Github.
Приложение содержит два компонента:
- поисковая строка пользователя Github;
- сцена с 3D визуализацией связей на three.js и react-three-fiber;
https://dawchihliou.github.io/articles/stress-testing-concurrent-features-in-react-18
В React 18 был добавлен конкурентный рендеринг. Основная его идея в том, что обновления стейта можно разделить на две категории:
- Срочные обновления: обеспечивают оперативный отклик на пользовательские события, например, ввод текста или скролл.
- Переходные обновления: представляют несрочные задачи для рендера UI, например, отображение датасета.
Цель переходных обновлений состоит в том, чтобы создать более отзывчивый интерфейс.
До React 18 все обновления стейта считались срочными и ввод текста или клик могли зафризить UI при рендере тяжелого компонента. В React 18 с помощью переходных обновлений рендер тяжелых компонентов будет происходить в фоне, в то время как UI будет оставаться отзывчивым.
Конкурентный рендеринг может выполнять следующие вещи:
- Yielding: React периодически ставит работу рендера на паузу, чтобы дать браузеру сделать другую работу.
- Прерывание: при появлении срочных задач React ставит рендер несрочной задачи на паузу и начинает рендерить срочную задачу, чтобы UI оставался отзывчивым.
- Отбрасывание старых результатов: если данные стейта для перехода устарели, то React отбрасывает старый рендер и начинает рендер по новой для свежего стейта.
Доу-Чи Лиу в своем блоге показал, как использовать API конкурентного рендеринга startTransition для рендера тяжелого компонента с 3D моделью с визуализацией связей между пользователями в Github.
Приложение содержит два компонента:
- поисковая строка пользователя Github;
- сцена с 3D визуализацией связей на three.js и react-three-fiber;
https://dawchihliou.github.io/articles/stress-testing-concurrent-features-in-react-18
dawchihliou.github.io
Stress Testing Concurrent Features in React 18: A Case Study of startTransition & 3D Rendering
React 18 released the highly anticipated concurrent features. In this article, we are diving into a 3D visualization and discuss how to optimize its performance step by step with React 18's concurrent rendering.
👍4
Plasmo – React фрейморвк для создания браузерных расширений
Plasmo – новый фреймворк на React и TypeScript для создания браузерных расширений. Особенности:
- live-reloading при дев разработке;
- файлы окружений;
- автоматический деплой;
- автоматическая генерация manifest.json;
- поддержка всех основных браузеров;
Также есть CLI для инициализации проекта. В фреймворке есть дополнительные библиотеки для работы с расширениями, например API постоянного хранилища, у которой есть интеграция с Redux.
https://docs.plasmo.com/
Plasmo – новый фреймворк на React и TypeScript для создания браузерных расширений. Особенности:
- live-reloading при дев разработке;
- файлы окружений;
- автоматический деплой;
- автоматическая генерация manifest.json;
- поддержка всех основных браузеров;
Также есть CLI для инициализации проекта. В фреймворке есть дополнительные библиотеки для работы с расширениями, например API постоянного хранилища, у которой есть интеграция с Redux.
https://docs.plasmo.com/
Plasmo Docs
Introduction to Plasmo – Plasmo
Plasmo is the end-to-end platform for browser extension developers - the easiest way to Build, Test and Ship browser extensions.
👍6
This media is not supported in your browser
VIEW IN TELEGRAM
Jest Preview для дебага тестов
При написании тестов с использованием Testing Library приходится писать много запросов в DOM, держа в голове структуру страницы, которую рендерит React для теста.
Для того чтобы видеть результат рендера во время теста, можно использовать библиотеку Jest Preview. После установки библиотеки и настройки конфигов, необходимо во время запуска тестов запускать команду jest-preview, которая будет стартовать сервер для превью тестов. В самих тестах, для отображения в браузере текущего DOM компонента, используется функция preview.debug().
Стоит учитывать, что в текущий момент библиотека активно развивается и может работать нестабильно.
https://www.jest-preview.com/
При написании тестов с использованием Testing Library приходится писать много запросов в DOM, держа в голове структуру страницы, которую рендерит React для теста.
Для того чтобы видеть результат рендера во время теста, можно использовать библиотеку Jest Preview. После установки библиотеки и настройки конфигов, необходимо во время запуска тестов запускать команду jest-preview, которая будет стартовать сервер для превью тестов. В самих тестах, для отображения в браузере текущего DOM компонента, используется функция preview.debug().
Стоит учитывать, что в текущий момент библиотека активно развивается и может работать нестабильно.
https://www.jest-preview.com/
👍7
React Labs: над чем мы работали – июнь 2022
React Labs — это новая серия статей: команда React хочет чаще делиться своим прогрессом. Команда работает над несколькими проектами и делится информацией о текущем состоянии. Это не дорожная карта, а исследовательские проекты, которые могут попасть в релиз.
- Серверные компоненты. Вместо использования внешней библиотеки для I/O будет использоваться async/await для лучшей совместимости. Откажутся от расширения у серверных файлов .server.js в пользу аннотаций внутри файла. Работают над унификацией для поддержки сборщиков Webpack/Vite.
- Asset Loading. Интеграция загрузки изображений, шрифтов, стилей и Suspense. Загрузка ассетов должна блокировать отображение, но не конкурентный рендеринг и стриминг.
- React Optimizing Compiler. Представили компилятор React Forget на React Conf 2021. Работа идет, недавно переписали компилятор на новую архитектуру.
- Offscreen. Предлагает новые возможности, например, мгновенный переход – рендер компонента в фоне.
https://reactjs.org/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.html
React Labs — это новая серия статей: команда React хочет чаще делиться своим прогрессом. Команда работает над несколькими проектами и делится информацией о текущем состоянии. Это не дорожная карта, а исследовательские проекты, которые могут попасть в релиз.
- Серверные компоненты. Вместо использования внешней библиотеки для I/O будет использоваться async/await для лучшей совместимости. Откажутся от расширения у серверных файлов .server.js в пользу аннотаций внутри файла. Работают над унификацией для поддержки сборщиков Webpack/Vite.
- Asset Loading. Интеграция загрузки изображений, шрифтов, стилей и Suspense. Загрузка ассетов должна блокировать отображение, но не конкурентный рендеринг и стриминг.
- React Optimizing Compiler. Представили компилятор React Forget на React Conf 2021. Работа идет, недавно переписали компилятор на новую архитектуру.
- Offscreen. Предлагает новые возможности, например, мгновенный переход – рендер компонента в фоне.
https://reactjs.org/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.html
react.dev
React Labs: What We've Been Working On – June 2022 – React
The library for web and native user interfaces
👍6
Инверсия управления и внедрение JSX через Context API
Инверсия управления – это принцип проектирования, который позволяет вызывающему коду контролировать внешнее окружение вызываемой программы. Использование этого принципа в React позволяет создавать более гибкие и кастомизируемые компоненты.
Для того, чтобы показать как использовать этот принцип в React, автор создал компонент переиспользуемой таблицы, в которой есть отдельный столбец с действиями над строками. У каждой строки может быть свой набор действий и, чтобы контролировать это, можно использовать IoC.
Для того чтобы рендерить для каждой строки кастомный набор действий, можно использовать контекст для передачи функции рендера. Функция рендера будет возвращать готовый JSX для рендера, который будет контролировать компонент, использующий таблицу.
https://theroadtoenterprise.com/blog/react-inversion-of-control-and-jsx-injection-via-context-api
Инверсия управления – это принцип проектирования, который позволяет вызывающему коду контролировать внешнее окружение вызываемой программы. Использование этого принципа в React позволяет создавать более гибкие и кастомизируемые компоненты.
Для того, чтобы показать как использовать этот принцип в React, автор создал компонент переиспользуемой таблицы, в которой есть отдельный столбец с действиями над строками. У каждой строки может быть свой набор действий и, чтобы контролировать это, можно использовать IoC.
Для того чтобы рендерить для каждой строки кастомный набор действий, можно использовать контекст для передачи функции рендера. Функция рендера будет возвращать готовый JSX для рендера, который будет контролировать компонент, использующий таблицу.
const TableColumnActions = props => {
const { row, column } = props;
const [openActions, setOpenActions] = useState(false);
useOnClickOutside(popupRef, () => setOpenActions(false));
const renderMenu = useTableActionsContext();
const menuOptions = renderMenu({
row,
column,
styles,
});
return (
<div className="relative">
{openActions ? (
<ul className={styles.actionsMenu}>{menuOptions}</ul>
) : null}
</div>
);
};
https://theroadtoenterprise.com/blog/react-inversion-of-control-and-jsx-injection-via-context-api
The Road To Enterprise Blog
React Enterprise Component Patterns - Inversion of Control and JSX Injection via Context API
In this article we will cover how to provide content to a deeply nested component by injecting JSX into a deeply nested component via Context API.
👍6
TypeScript шпаргалка для React
Если вы уже работаете с React и JS и планируете использовать TypeScript, то рекомендую изучить данный сайт. В нем собраны и разбиты по категориям инструкции по работе с React и TypeScript: как использовать TS вместе с хуками, функциональными компонентами, классами и т.д.
Также есть раздел со списком полезных паттернов для React появившемся в определенной версии TypeScript. Например, в TypeScript 4.1 появились типы шаблонных литералов, которые позволяют моделировать динамические типы в строковых литералах. Это может использоваться при типизации роутера:
https://react-typenoscript-cheatsheet.netlify.app/
Если вы уже работаете с React и JS и планируете использовать TypeScript, то рекомендую изучить данный сайт. В нем собраны и разбиты по категориям инструкции по работе с React и TypeScript: как использовать TS вместе с хуками, функциональными компонентами, классами и т.д.
Также есть раздел со списком полезных паттернов для React появившемся в определенной версии TypeScript. Например, в TypeScript 4.1 появились типы шаблонных литералов, которые позволяют моделировать динамические типы в строковых литералах. Это может использоваться при типизации роутера:
type ParseRouteParams<Rte> = Rte extends `${string}/:${infer P}` ? P : never;
type Params = ParseRouteParams<"/api/user/:userID">; // Params is "userID"
https://react-typenoscript-cheatsheet.netlify.app/
react-typenoscript-cheatsheet.netlify.app
React TypeScript Cheatsheets | React TypeScript Cheatsheets
🔥7
Компонент и элемент в React
В терминах React встречаются такие слова как компонент, элемент и экземпляр. Чтобы разобраться в них и понять как они работают, давайте посмотрим на примеры:
Код выше является объявлением React компонента. Если конкретнее, то это функциональный компонент (объявления классовых компонентов тоже являются компонентами). Рендеринг компонента происходит, когда мы используем его этот компонент как React элемент с угловыми скобками (например <Greeting />) в другом компоненте:
Мы можем отрендерить компонент как элемент несколько раз. Каждый раз, когда мы рендерим компонент как элемент, мы создаем экземпляр данного компонента:
Хоть компонент и объявлен один раз, он может использоваться несколько раз. При рендере он становится экземпляром компонента и живет в дереве React.
Робин Верух в своем блоге разобрался, как происходит рендер элементов и почему не стоит вызывать компонент как функцию при рендере в другом компоненте.
https://www.robinwieruch.de/react-element-component/
В терминах React встречаются такие слова как компонент, элемент и экземпляр. Чтобы разобраться в них и понять как они работают, давайте посмотрим на примеры:
const App = () => {
return <p>Hello React</p>;
};
Код выше является объявлением React компонента. Если конкретнее, то это функциональный компонент (объявления классовых компонентов тоже являются компонентами). Рендеринг компонента происходит, когда мы используем его этот компонент как React элемент с угловыми скобками (например <Greeting />) в другом компоненте:
const Greeting = ({ text }) => {
return <p>{text}</p>;
};
const App = () => {
return <Greeting text="Hello React" />;
};
Мы можем отрендерить компонент как элемент несколько раз. Каждый раз, когда мы рендерим компонент как элемент, мы создаем экземпляр данного компонента:
const App = () => {
return (
<>
<Greeting text="Hello Instance 1 of Greeting" />
<Greeting text="Hello Instance 2 of Greeting" />
</>
);
};
Хоть компонент и объявлен один раз, он может использоваться несколько раз. При рендере он становится экземпляром компонента и живет в дереве React.
Робин Верух в своем блоге разобрался, как происходит рендер элементов и почему не стоит вызывать компонент как функцию при рендере в другом компоненте.
https://www.robinwieruch.de/react-element-component/
www.robinwieruch.de
React Element vs Component
What are React Elements, Components, and Instances? A step by step explanation for a better ...
👍4👎4
Обзор Redux Toolkit
Если вы еще не пробовали Redux Toolkit (RTK), то рекомендую прочитать краткий обзор от Марка Эриксона, создателя данного инструмента. В нем он рассказывает об основных API и подходах к разработке с использованием RTK, а также призывает всех пользователей Redux начать использовать RTK. Если кратко, то основные тезисы в пользу использования RTK:
- упрощает настройку стора до вызова одной функции;
- устраняет случайную мутацию стора и упрощает изменение стейта;
- избавляет от необходимости ручного написания action creators;
- упрощает написание логики фичи в одном файле вместо распределения его по нескольким файлам;
- хорошая поддержка TypeScript из коробки;
- RTK Query позволяет избавиться от написания thunks, редьюсеров, actions creators и дополнительных хуков для управления данными и отслеживанием стейта запроса;
https://blog.isquaredsoftware.com/presentations/2022-06-modern-redux-rtk/?slideIndex=0&stepIndex=0
Если вы еще не пробовали Redux Toolkit (RTK), то рекомендую прочитать краткий обзор от Марка Эриксона, создателя данного инструмента. В нем он рассказывает об основных API и подходах к разработке с использованием RTK, а также призывает всех пользователей Redux начать использовать RTK. Если кратко, то основные тезисы в пользу использования RTK:
- упрощает настройку стора до вызова одной функции;
- устраняет случайную мутацию стора и упрощает изменение стейта;
- избавляет от необходимости ручного написания action creators;
- упрощает написание логики фичи в одном файле вместо распределения его по нескольким файлам;
- хорошая поддержка TypeScript из коробки;
- RTK Query позволяет избавиться от написания thunks, редьюсеров, actions creators и дополнительных хуков для управления данными и отслеживанием стейта запроса;
https://blog.isquaredsoftware.com/presentations/2022-06-modern-redux-rtk/?slideIndex=0&stepIndex=0
Isquaredsoftware
Modern Redux with Redux Toolkit, June 2022
Presentation slides for this talk, June 2022
👍4👎3🔥3
Storybook Community Showcase
Сводка последних новостей от сообщества Storybook: энциклопедия компонентов, плагин Figma, Story Explorer и различные аддоны: Variants, переменные CSS, Recoil…
- Энциклопедия компонентов. В Storybook собрали большую коллекцию популярных UI библиотек от Airbnb, Wix, WordPress и других. Теперь при создании своей UI библиотеки можно подсмотреть идеи у лучших компаний.
- Figma плагин для дизайн ревью. С помощью плагина Storybook Connect можно смотреть Storybook истории прямо в дизайне фигмы и тестировать компонент в живую.
- Обозреватель историй VSCode. Позволяет запускать истории в редакторе.
https://storybook.js.org/blog/community-showcase-2/
Сводка последних новостей от сообщества Storybook: энциклопедия компонентов, плагин Figma, Story Explorer и различные аддоны: Variants, переменные CSS, Recoil…
- Энциклопедия компонентов. В Storybook собрали большую коллекцию популярных UI библиотек от Airbnb, Wix, WordPress и других. Теперь при создании своей UI библиотеки можно подсмотреть идеи у лучших компаний.
- Figma плагин для дизайн ревью. С помощью плагина Storybook Connect можно смотреть Storybook истории прямо в дизайне фигмы и тестировать компонент в живую.
- Обозреватель историй VSCode. Позволяет запускать истории в редакторе.
https://storybook.js.org/blog/community-showcase-2/
storybook.js.org
Showcase | Storybook
Explore 1000s of components and libraries
👍6
Возможно вам не нужны эффекты
Эффекты – это выход из парадигмы React. Они позволяют синхронизировать компоненты с какой-либо внешней системой, такой как виджет, не относящийся к React, сеть или DOM браузера. Если не задействована какая-то внешняя система (например, изменение стейта при обновлении какого-то пропа), вам не нужен эффект.
Основные случаи, когда эффект не нужен:
- Обновление стейта при обновлении стейта или пропа. Вместо этого используйте производные переменные.
- Кэширование вычислений. Используйте useMemo.
- Сброс стейта при изменении пропа. Установите изменяющийся проп в проп key. При изменении key, React пересоздает DOM и сбрасывает стейт у компонента и всех его потомков.
- Получение данных. Если делаете fetch в эффекте, то используйте cleanup функцию для отмены запроса, чтобы предотвратить race condition. Также есть комментарий Дэна Абрамова про рекомендованный способ получения данных в React 18.
https://beta.reactjs.org/learn/you-might-not-need-an-effect
Эффекты – это выход из парадигмы React. Они позволяют синхронизировать компоненты с какой-либо внешней системой, такой как виджет, не относящийся к React, сеть или DOM браузера. Если не задействована какая-то внешняя система (например, изменение стейта при обновлении какого-то пропа), вам не нужен эффект.
Основные случаи, когда эффект не нужен:
- Обновление стейта при обновлении стейта или пропа. Вместо этого используйте производные переменные.
- Кэширование вычислений. Используйте useMemo.
- Сброс стейта при изменении пропа. Установите изменяющийся проп в проп key. При изменении key, React пересоздает DOM и сбрасывает стейт у компонента и всех его потомков.
- Получение данных. Если делаете fetch в эффекте, то используйте cleanup функцию для отмены запроса, чтобы предотвратить race condition. Также есть комментарий Дэна Абрамова про рекомендованный способ получения данных в React 18.
https://beta.reactjs.org/learn/you-might-not-need-an-effect
Reddit
gaearon's comment on "What is the recommended way to load data for React 18?"
Explore this conversation and more from the reactjs community
👍9
React Query FAQ
Доминик Дорфмайстер, один из разработчиков библиотеки React Query, написал в своем блоге FAQ по библиотеке react-query, в которой ответил на наиболее популярные вопросы.
- Как передать параметр в refetch? Если кратко, то это сделать нельзя, т.к. нарушается принцип работы react-query. React-query кэширует результат запроса по ключу, переданному в хук в первом параметре, поэтому refetch только повторяет запрос. Если нужно выполнить refetch с другими параметрами, то это значит, что нужно сделать новый запрос с новым ключом.
- Состояние загрузки. Чтобы сохранить предыдущее значение data при изменении ключа до загрузки новых данных, можно использовать параметр keepPreviousData. Дополнительно можно использовать флаг isPreviousData, который обозначает что в data находится устаревшее значение.
- Почему не обновляется кэш? При работе напрямую с Query Cache бывают моменты, когда кэш не обновляется. Одна из причин – не совпадают ключи. Когда вызываете queryClient.setQueryData, ключи запроса должны полностью совпадать с существующими. Например, следующие ключи не будут совпадать, потому что ‘1’ !== 1:
Еще одна возможная причина того, что не обновляет кэш – нестабильная ссылка на QueryClient в QueryClientProvider. Лучше всего объявлять QueryClient вне компонента, но если нужно объявить его внутри компонента, то объявляйте внутри рефа или useState:
https://tkdodo.eu/blog/react-query-fa-qs
Доминик Дорфмайстер, один из разработчиков библиотеки React Query, написал в своем блоге FAQ по библиотеке react-query, в которой ответил на наиболее популярные вопросы.
- Как передать параметр в refetch? Если кратко, то это сделать нельзя, т.к. нарушается принцип работы react-query. React-query кэширует результат запроса по ключу, переданному в хук в первом параметре, поэтому refetch только повторяет запрос. Если нужно выполнить refetch с другими параметрами, то это значит, что нужно сделать новый запрос с новым ключом.
const { data } = useQuery(['item', id], () => fetchItem({ id }))
- Состояние загрузки. Чтобы сохранить предыдущее значение data при изменении ключа до загрузки новых данных, можно использовать параметр keepPreviousData. Дополнительно можно использовать флаг isPreviousData, который обозначает что в data находится устаревшее значение.
const { data, isPreviousData } = useQuery(
['item', id],
() => fetchItem({ id }),
{ keepPreviousData: true }
)
- Почему не обновляется кэш? При работе напрямую с Query Cache бывают моменты, когда кэш не обновляется. Одна из причин – не совпадают ключи. Когда вызываете queryClient.setQueryData, ключи запроса должны полностью совпадать с существующими. Например, следующие ключи не будут совпадать, потому что ‘1’ !== 1:
['item', '1']
['item', 1]
Еще одна возможная причина того, что не обновляет кэш – нестабильная ссылка на QueryClient в QueryClientProvider. Лучше всего объявлять QueryClient вне компонента, но если нужно объявить его внутри компонента, то объявляйте внутри рефа или useState:
export default function App() {
const [queryClient] = React.useState(() => new QueryClient())
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}
https://tkdodo.eu/blog/react-query-fa-qs
tkdodo.eu
React Query FAQs
Answering the most frequently asked React Query questions
👍4
Получение данных и Suspense
Suspense позволяет приостановить рендеринг компонента. Например, если в нем выполняются асинхронные операции, такие как получение данных, то Suspense отложит рендер данного компонента.
Но как Suspense понимает, что внутри компонента происходит сетевой запрос на получение данных? Suspense рендерит индикатор загрузки, но в коде мы нигде не сообщаем React, что делаем сетевой запрос. Если вы используете библиотеки react-query, SWR, то в них есть поддержка Suspense. Давайте попробуем сделать поддержку Suspense для Axios.
Чтобы Suspense узнал о том, что в компоненте происходит асинхронная операция, нужно выкинуть исключение в виде промиса. Можно сделать функцию, которая бы делала это с любыми промисами и обернуть ее в сетевые запросы:
Применение данной функции:
Таким образом, Suspense увидит, что в компоненте UserProfile происходит сетевой запрос и покажет индикатор загрузки.
https://blog.openreplay.com/data-fetching-with-suspense-in-react
Suspense позволяет приостановить рендеринг компонента. Например, если в нем выполняются асинхронные операции, такие как получение данных, то Suspense отложит рендер данного компонента.
Но как Suspense понимает, что внутри компонента происходит сетевой запрос на получение данных? Suspense рендерит индикатор загрузки, но в коде мы нигде не сообщаем React, что делаем сетевой запрос. Если вы используете библиотеки react-query, SWR, то в них есть поддержка Suspense. Давайте попробуем сделать поддержку Suspense для Axios.
Чтобы Suspense узнал о том, что в компоненте происходит асинхронная операция, нужно выкинуть исключение в виде промиса. Можно сделать функцию, которая бы делала это с любыми промисами и обернуть ее в сетевые запросы:
const dataFetch = () => {
const userPromise = fetchUser;
return {
user: wrapPromise(userPromise),
};
};
const wrapPromise = (promise) => {
let status = "pending";
let result;
let suspend = promise().then(
(res) => {
status = "success";
result = res;
},
(err) => {
status = "error";
result = err;
}
);
return {
read() {
if (status === "pending") {
throw suspend;
} else if (status === "error") {
throw result;
} else if (status === "success") {
return result;
}
},
};
};
Применение данной функции:
const resource = dataFetch();
const UserProfile = () => {
const user = resource.user.read();
return (
<div className="container">
<h1 className="noscript">{user.name}</h1>
</div>
);
};
Таким образом, Suspense увидит, что в компоненте UserProfile происходит сетевой запрос и покажет индикатор загрузки.
https://blog.openreplay.com/data-fetching-with-suspense-in-react
Openreplay
Data fetching with Suspense in React
Use the new Suspense technique for simpler data fetching
👍6👎2
Уже в этот четверг 21 июля в 19 МСК друзья из AgileFluent и Solvery проведут бесплатное live собеседование на английском с software engineer.
Интервьюеры:
Маша Реутская, международный HR эксперт AgileFluent, 15+ лет опыта in-house в крупнейших международных компаниях.
Проведёт софт-скилл интервью и даст фидбек, как улучшить ответы.
Саша Черношей, Software engineer в Microsoft в Эстонии, ментор Solvery. 6 лет опыта разработки ПО и 4 года мобильной разработки на react-native для заказчиков из США и Великобритании. Проведет техническую часть интервью.
📆Дата и время: 21 июля, 19:00 по Мск.
Будет полезно разработчикам, которые хотят в международную компанию или готовятся к тех интервью. И всем, кто готовится к behavioral-интервью: эта часть схожая у всех профессий.
Будет интервью с кандидатом из зала — если хочешь в поучаствовать и получить фидбэк от рекрутера и нанимающего менеджера, заполняй форму тут. Очень ждем на интервью реакт-нейтивов.
Записаться и получить запись можно в боте.
Интервьюеры:
Маша Реутская, международный HR эксперт AgileFluent, 15+ лет опыта in-house в крупнейших международных компаниях.
Проведёт софт-скилл интервью и даст фидбек, как улучшить ответы.
Саша Черношей, Software engineer в Microsoft в Эстонии, ментор Solvery. 6 лет опыта разработки ПО и 4 года мобильной разработки на react-native для заказчиков из США и Великобритании. Проведет техническую часть интервью.
📆Дата и время: 21 июля, 19:00 по Мск.
Будет полезно разработчикам, которые хотят в международную компанию или готовятся к тех интервью. И всем, кто готовится к behavioral-интервью: эта часть схожая у всех профессий.
Будет интервью с кандидатом из зала — если хочешь в поучаствовать и получить фидбэк от рекрутера и нанимающего менеджера, заполняй форму тут. Очень ждем на интервью реакт-нейтивов.
Записаться и получить запись можно в боте.
👍4🔥2
Тайна React Element и повторные рендеры
Например, у вас есть родительский компонент, в котором часто изменяется стейт. В нем рендерится дочерний компонент:
Изменение стейта в родительском компоненте будет приводить к рендеру дочернего компонента, что может быть плохо для производительности. Чтобы предотвратить повторный рендер дочернего компонента, помимо React.memo можно использовать паттерн children, когда ChildComponent выносится наружу и передается как проп children:
Надя Макаревич в своем блоге разобралась, почему React не рендерит компонент повторно в таком случае, а почему в других случаях происходит рендер.
В случае передачи компонента как проп children, компонент создается один раз в SomeOutsideComponent. При рендере компонента MovingComponent, при изменении стейта его пропсы остаются такими же, поэтому не происходит повторный рендер компонента ChildComponent.
https://www.developerway.com/posts/react-elements-children-parents
Например, у вас есть родительский компонент, в котором часто изменяется стейт. В нем рендерится дочерний компонент:
const MovingComponent = () => {
const [state, setState] = useState({ x: 100, y: 100 });
return (
<div onMouseMove={(e) => setState({ x: e.clientX - 20, y: e.clientY - 20 })} style={{ left: state.x, top: state.y }}>
<ChildComponent />
</div>
);
};
Изменение стейта в родительском компоненте будет приводить к рендеру дочернего компонента, что может быть плохо для производительности. Чтобы предотвратить повторный рендер дочернего компонента, помимо React.memo можно использовать паттерн children, когда ChildComponent выносится наружу и передается как проп children:
const MovingComponent = ({ children }) => {
const [state, setState] = useState({ x: 100, y: 100 });
return (
<div onMouseMove={(e) => setState({ x: e.clientX - 20, y: e.clientY - 20 })} style={{ left: state.x, top: state.y }}>
{children}
</div>
);
};
const SomeOutsideComponent = () => {
return (
<MovingComponent>
<ChildComponent />
</MovingComponent>
);
};
Надя Макаревич в своем блоге разобралась, почему React не рендерит компонент повторно в таком случае, а почему в других случаях происходит рендер.
В случае передачи компонента как проп children, компонент создается один раз в SomeOutsideComponent. При рендере компонента MovingComponent, при изменении стейта его пропсы остаются такими же, поэтому не происходит повторный рендер компонента ChildComponent.
https://www.developerway.com/posts/react-elements-children-parents
Developerway
The mystery of React Element, children, parents and re-renders
Looking into what is React Element, exploring various children vs parents relationship in React, and how they affect re-renders
👍15
Изучаем исходный код React
В блоге Алексея Кондова вышла статья, в которой он рассказал про свой опыт изучения исходного кода React. В самой статье автор рассказывает о дизайн-принципах, которые использовала команда React при разработке библиотеки, и делится своими мыслями о конструкциях в коде.
Например, при вызове createRoot из ReactDOM будет создаваться объект ReactDOMRoot:
Эта функция всего лишь сохраняет переданное значение в this и ничего не возвращает. Методы этой функции, например render, будут объявляться через прототип:
Этот подход имеет свои преимущества. Во-первых, можно использовать оператор instanceof для проверки типа объекта (instanceof будет проверять цепочку прототипа). Во-вторых, это более производительнее. Функция прототипа создается один раз, в отличии от замыканий.
https://alexkondov.com/readint-source-code-react/
В блоге Алексея Кондова вышла статья, в которой он рассказал про свой опыт изучения исходного кода React. В самой статье автор рассказывает о дизайн-принципах, которые использовала команда React при разработке библиотеки, и делится своими мыслями о конструкциях в коде.
Например, при вызове createRoot из ReactDOM будет создаваться объект ReactDOMRoot:
function ReactDOMRoot(internalRoot: FiberRoot) {
this._internalRoot = internalRoot
}
Эта функция всего лишь сохраняет переданное значение в this и ничего не возвращает. Методы этой функции, например render, будут объявляться через прототип:
ReactDOMHydrationRoot.prototype.render =
ReactDOMRoot.prototype.render = function (
children: ReactNodeList
): void {
const root = this._internalRoot
// …
}
Этот подход имеет свои преимущества. Во-первых, можно использовать оператор instanceof для проверки типа объекта (instanceof будет проверять цепочку прототипа). Во-вторых, это более производительнее. Функция прототипа создается один раз, в отличии от замыканий.
https://alexkondov.com/readint-source-code-react/
Alexkondov
Reading Code - React
It’s daunting to even think about reading the code of a framework I’ve been using for years. I’ve always seen React as a black box that takes JSX and puts…
🔥5
React Core Team не рекомендует CSS-in-JS runtime библиотеки
В недавнем Q&A интервью Дэн Абрамов поделился мнением насчет стилей в React приложениях. Основной посыл был в том, что если используются динамические стили, то лучше применять инлайновые стили у элемента. Если стили не динамические, то лучше использовать что-то, что компилируется в CSS при сборке приложения и не использует runtime.
Это утверждение совпадает с мнением Себастьяна Маркбоге, одного из ментейнера React. Он рекомендует выносить статичные стили при компиляции в
Одними из популярных CSS-in-JS библиотек, которые генерируют стили в runtime, являются Emotion и Styled Components. Одной из проблем этих библиотек является их производительность. Браузер во время загрузки страницы может параллельно парсить JS, CSS и HTML. В случае CSS-in-JS runtime библиотек сначала надо спарсить и запустить JS, который сгенерирует стили, и спарсить их отдельно.
В недавнем Q&A интервью Дэн Абрамов поделился мнением насчет стилей в React приложениях. Основной посыл был в том, что если используются динамические стили, то лучше применять инлайновые стили у элемента. Если стили не динамические, то лучше использовать что-то, что компилируется в CSS при сборке приложения и не использует runtime.
Это утверждение совпадает с мнением Себастьяна Маркбоге, одного из ментейнера React. Он рекомендует выносить статичные стили при компиляции в
<link rel="stylesheet">. Одними из популярных CSS-in-JS библиотек, которые генерируют стили в runtime, являются Emotion и Styled Components. Одной из проблем этих библиотек является их производительность. Браузер во время загрузки страницы может параллельно парсить JS, CSS и HTML. В случае CSS-in-JS runtime библиотек сначала надо спарсить и запустить JS, который сгенерирует стили, и спарсить их отдельно.
YouTube
Devs For Ukraine - Q&A with Dan Abramov
In this Q&A, Cassidy Williams and Sara Vieira ask Dan Abramov questions from the developer community about React, the web, the future, and more.
https://www.devsforukraine.io/
https://www.devsforukraine.io/
👍16👎4❤1
Применение принципов SOLID в React
Принципы SOLID находят свое применение не только в ООП, их можно применить и при разработке приложения React. Пользуясь этими принципами, можно обеспечить хорошую декомпозицию компонентов приложения.
В своем блоге Константин Лебедев интерпретировал принципы SOLID в коде React. Например, как можно применить принцип разделения интерфейса:
Компонент Thumbnail принимает объект video, хотя для работы данного компонента требуется только ссылка на изображение. Чтобы показать проблему, добавим новый тип видео в VideoList, у которого будет отличаться интерфейс объекта. В этом случае Thumbnail будет работать неправильно и его придется переделать. Сделаем так, чтобы Thumbnail принимал проп coverUrl – ссылку на изображение и будем передавать туда нужный проп в зависимости от типа видео:
Принцип разделения интерфейса отвечает за минимизацию зависимостей между компонентами системы, делая их менее связанными и переиспользуемыми.
https://konstantinlebedev.com/solid-in-react/
Принципы SOLID находят свое применение не только в ООП, их можно применить и при разработке приложения React. Пользуясь этими принципами, можно обеспечить хорошую декомпозицию компонентов приложения.
В своем блоге Константин Лебедев интерпретировал принципы SOLID в коде React. Например, как можно применить принцип разделения интерфейса:
// VideoList.tsx
type Video = {
noscript: string
duration: number
coverUrl: string
}
type Props = {
items: Array<Video>
}
const VideoList = ({ items }) => {
return (
<ul>
{items.map(item =>
<Thumbnail
key={item.noscript}
video={item}
/>
)}
</ul>
)
}
// Thumbnail.tsx
type Props = {
video: Video
}
const Thumbnail = ({ video }: Props) => {
return <img src={video.coverUrl} />
}
Компонент Thumbnail принимает объект video, хотя для работы данного компонента требуется только ссылка на изображение. Чтобы показать проблему, добавим новый тип видео в VideoList, у которого будет отличаться интерфейс объекта. В этом случае Thumbnail будет работать неправильно и его придется переделать. Сделаем так, чтобы Thumbnail принимал проп coverUrl – ссылку на изображение и будем передавать туда нужный проп в зависимости от типа видео:
type Props = {
items: Array<Video | LiveStream>
}
const VideoList = ({ items }) => {
return (
<ul>
{items.map(item => {
if ('coverUrl' in item) {
// it's a video
return <Thumbnail coverUrl={item.coverUrl} />
} else {
// it's a live stream
return <Thumbnail coverUrl={item.previewUrl} />
}
})}
</ul>
)
}
Принцип разделения интерфейса отвечает за минимизацию зависимостей между компонентами системы, делая их менее связанными и переиспользуемыми.
https://konstantinlebedev.com/solid-in-react/
Konstantinlebedev
Applying SOLID principles in React
As the software industry grows and makes mistakes, the best practices and good software design principles emerge and conceptualize to avoid repeating the same…
👍10
Date & Time picker для всех
UI библиотека от Adobe, React Spectrum, представила новые инструменты для работы с датой и временем для React – хуки useDateField и useTimeField. Также есть инструменты для работы с календарем useCalendar и useRangeCalendar. Помимо хуков есть стилизованные компоненты для работы с датой, временем и календарем.
Для работы с интернационализацией Adobe представила библиотеку
https://react-spectrum.adobe.com/blog/date-and-time-pickers-for-all.html
UI библиотека от Adobe, React Spectrum, представила новые инструменты для работы с датой и временем для React – хуки useDateField и useTimeField. Также есть инструменты для работы с календарем useCalendar и useRangeCalendar. Помимо хуков есть стилизованные компоненты для работы с датой, временем и календарем.
Для работы с интернационализацией Adobe представила библиотеку
@internationalized/date. В ней вместо использования стандартного объекта Date используются новые объекты для работы с датой и временем, с разным поведением и для разных кейсов. Например, CalendarDate представляет из себя только дату без времени, а Time только время без даты. Объекты поддерживают арифметические операции и их можно между собой сравнивать. В целом, получилась альтернатива Moment.js и другим подобным библиотекам. https://react-spectrum.adobe.com/blog/date-and-time-pickers-for-all.html
Adobe
Date and Time Pickers for All
We are very excited to announce the release of the React Aria and React Spectrum date and time picker components! This includes a full suite of fully featured components and hooks including calendars, date and time fields, and range pickers, all with a focus…
👍4
Как использовать Next.js мидлвары
В блоге Криса Николаса вышла статья о том, как можно использовать Next.js мидлвары. Файл мидлвара должен лежать в корневой папке проекта с названием middleware.ts.
Эта функция будет запускаться перед каждой загрузкой страницы, API роута или файла на сайте. Мидлвар не может возвращать Response. Также можно настроить работу мидлвара только для отдельных страниц, экспортировав config с массивом URL в файле middleware.ts:
Какие есть возможные варианты использования мидлваров:
- Редирект на другую страницу.
- Переписывание страницы, т.е. использование другой страницы для данного URL.
- Проверка UserAgent. Можно делать редирект или переписывание страницы на мобильную/десктопную версию сайта.
- Проверка доступа. Можно получить из запроса токен пользователя и проверить доступ к странице.
- Счетчик посещений.
https://www.ctnicholas.dev/articles/how-to-use-nextjs-middleware
В блоге Криса Николаса вышла статья о том, как можно использовать Next.js мидлвары. Файл мидлвара должен лежать в корневой папке проекта с названием middleware.ts.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware (request: NextRequest) {
return NextResponse.next()
}
Эта функция будет запускаться перед каждой загрузкой страницы, API роута или файла на сайте. Мидлвар не может возвращать Response. Также можно настроить работу мидлвара только для отдельных страниц, экспортировав config с массивом URL в файле middleware.ts:
export const config = {
matcher: ['/about', '/articles/:path*']
}
Какие есть возможные варианты использования мидлваров:
- Редирект на другую страницу.
- Переписывание страницы, т.е. использование другой страницы для данного URL.
- Проверка UserAgent. Можно делать редирект или переписывание страницы на мобильную/десктопную версию сайта.
- Проверка доступа. Можно получить из запроса токен пользователя и проверить доступ к странице.
- Счетчик посещений.
// Мидлвар проверки доступа
const secretKey = 'artichoke'
export function middleware (request: NextRequest) {
if (request.nextUrl.pathname === '/api/query') {
const headerKey = request.headers.get('secret-key')
// If secret keys match, allow access
if (headerKey === secretKey) {
return NextResponse.next()
}
// Otherwise, redirect to your custom error page
const url = request.nextUrl.clone()
url.pathname = '/unauthorised'
return NextResponse.redirect(url)
}
return NextResponse.next()
}
https://www.ctnicholas.dev/articles/how-to-use-nextjs-middleware
CTNicholas
How to Use Next.js Middleware • CTNicholas
With the release of Next.js 12, Vercel Edge Functions have been announced, allowing for
super speedy edge-optimised functions. They can also be used as helpful Next.js middleware functions.
In this article I'll explain what they are & how to use them, before…
super speedy edge-optimised functions. They can also be used as helpful Next.js middleware functions.
In this article I'll explain what they are & how to use them, before…
👍8
Подборка React компонентов и библиотек
Курируемый список компонентов и библиотек для разных кейсов. Мейнтейнеры собрали список из полезных компонентов и библиотек, которые решают проблемы в своей области.
Список разнообразный и разбит по категориям: от текстовых редакторов до древовидных меню и библиотек интернационализаций.
https://github.com/brillout/awesome-react-components
Курируемый список компонентов и библиотек для разных кейсов. Мейнтейнеры собрали список из полезных компонентов и библиотек, которые решают проблемы в своей области.
Список разнообразный и разбит по категориям: от текстовых редакторов до древовидных меню и библиотек интернационализаций.
https://github.com/brillout/awesome-react-components
GitHub
GitHub - brillout/awesome-react-components: Curated List of React Components & Libraries.
Curated List of React Components & Libraries. Contribute to brillout/awesome-react-components development by creating an account on GitHub.
👍5
HolyJS возвращается!
В ноябре JUG Ru Group организует конференцию для JavaScript‑разработчиков — HolyJS 2022. В программе — технические доклады и дискуссии о языках, архитектуре, графике, фреймворках и инструментах. На конференции соберутся все, кто программирует на JavaScript, — для фронтенда и не только.
Участники конференции любят обсуждать нетривиальные задачи и новые подходы в JavaScript-разработке. Есть интересные кейсы? Тогда подавайте заявку на выступление. Программный комитет поможет с подготовкой к выступлению: назначит персонального куратора, проведет ревью материала и организует репетиции.
Выбирайте тему выступления на сайте или предлагайте свои идеи — их обязательно рассмотрят.
Всем спикерам JUG Ru Group дарит билет на все конференции сезона в онлайне и офлайне.
А билеты можно купить здесь.
В ноябре JUG Ru Group организует конференцию для JavaScript‑разработчиков — HolyJS 2022. В программе — технические доклады и дискуссии о языках, архитектуре, графике, фреймворках и инструментах. На конференции соберутся все, кто программирует на JavaScript, — для фронтенда и не только.
Участники конференции любят обсуждать нетривиальные задачи и новые подходы в JavaScript-разработке. Есть интересные кейсы? Тогда подавайте заявку на выступление. Программный комитет поможет с подготовкой к выступлению: назначит персонального куратора, проведет ревью материала и организует репетиции.
Выбирайте тему выступления на сайте или предлагайте свои идеи — их обязательно рассмотрят.
Всем спикерам JUG Ru Group дарит билет на все конференции сезона в онлайне и офлайне.
А билеты можно купить здесь.
👍4