Использование Rust в React приложениях
Джош Финни рассказывает, как использовать Rust в React приложениях. Для возможности использования Rust в вебе необходимо использовать модуль wasm-bindgen. Этот модуль генерирует биндинги для использования Rust программ через Wasm в вебе.
Использование Rust, как и например C, C++ или Go, через WebAssembly обеспечивает скорость выполнения кода близкой к нативной. WebAssembly также дает возможность переносить сложные вычисления за пределы JavaScript.
https://www.joshfinnie.com/blog/using-webassembly-created-in-rust-for-fast-react-components/
🇷🇺 https://habr.com/ru/company/timeweb/blog/594967/
Джош Финни рассказывает, как использовать Rust в React приложениях. Для возможности использования Rust в вебе необходимо использовать модуль wasm-bindgen. Этот модуль генерирует биндинги для использования Rust программ через Wasm в вебе.
Использование Rust, как и например C, C++ или Go, через WebAssembly обеспечивает скорость выполнения кода близкой к нативной. WebAssembly также дает возможность переносить сложные вычисления за пределы JavaScript.
https://www.joshfinnie.com/blog/using-webassembly-created-in-rust-for-fast-react-components/
🇷🇺 https://habr.com/ru/company/timeweb/blog/594967/
Joshfinnie
Using WebAssembly (created in Rust) for Fast React Components | www.joshfinnie.com
In this blog post we will learn how to leverage the Rust programming language to compile WebAssembly which we will then use in our React application. This gives us access to low-level components to speed up our code!
Эффективный рендер больших списков
При работе с большими списками данных при проблемах с производительностью стоит обратить внимание на виртуализацию списка. Одна из таких библиотек для React – react-window. Библиотека умеет делать виртуализацию списка и сетки элементов с фиксированным или динамическим размером.
Виртуализация списка позволяет улучшить производительность страницы в целом, уменьшив количество отрендендеренных элементов. При скролле списка рендерятся в DOM только те элементы, которые находятся в поле видимости для пользователя. Если элемент покидает поле видимости, то он удаляется из DOM.
https://web.dev/virtualize-long-lists-react-window/
При работе с большими списками данных при проблемах с производительностью стоит обратить внимание на виртуализацию списка. Одна из таких библиотек для React – react-window. Библиотека умеет делать виртуализацию списка и сетки элементов с фиксированным или динамическим размером.
Виртуализация списка позволяет улучшить производительность страницы в целом, уменьшив количество отрендендеренных элементов. При скролле списка рендерятся в DOM только те элементы, которые находятся в поле видимости для пользователя. Если элемент покидает поле видимости, то он удаляется из DOM.
https://web.dev/virtualize-long-lists-react-window/
web.dev
Virtualize large lists with react-window | Articles | web.dev
react-window is a library that allows large lists to be rendered efficiently.
Архитектура веб-приложений patterns.dev
Адди Османи и Лидия Холли представили книгу с описанием шаблонов проектирования приложений. Книгу также можно почитать прямо на сайте проекта.
В ней есть как стандартные шаблоны проектирования, такие как Singleton, Factory и т.д., так и шаблоны рендеринга, например, рассматривается React Server Components.
В книге есть три раздела: шаблоны проектирования, рендеринга и производительности. В главах есть примеры реализации шаблонов на React или на ванильном JS.
https://www.patterns.dev/
Адди Османи и Лидия Холли представили книгу с описанием шаблонов проектирования приложений. Книгу также можно почитать прямо на сайте проекта.
В ней есть как стандартные шаблоны проектирования, такие как Singleton, Factory и т.д., так и шаблоны рендеринга, например, рассматривается React Server Components.
В книге есть три раздела: шаблоны проектирования, рендеринга и производительности. В главах есть примеры реализации шаблонов на React или на ванильном JS.
https://www.patterns.dev/
www.patterns.dev
Learn JavaScript design and performance patterns for building more powerful web applications.
Ленивая инициализация useRef
Владимир Клепов поделился техникой создания ленивой инициализации хука useRef. В отличие от useState, хук useRef не принимает функцию для инициализации значения. Ленивая инициализация может улучшить производительность компонента, т.к. позволяет вычислить значение рефа в момент его использования, а не при рендере компонента.
Есть несколько подходов к реализации данной техники:
- Установка значения рефа в useEffect. Минус в том, что значение рефа не будет доступно в первый рендер, в useLayoutEffect, а также в дочерних useEffect.
- Кастомный хук с инициализацией на месте. Минус подхода в том, что функция инициализации выполняется даже если значение рефа было не нужно. Также инициализация блокирует первый рендер.
- Использовать useState. Хук можно использовать как реф если игнорировать функцию обновления. В этом случае, в хуке будет записана ссылка на один объект, и его изменение не будет вызывать ререндер.
- Создать кастомный хук с полями аксессорами (accessor properties). Если у объекта задать геттер и сеттер на поле current и внутри использовать реф, то получится правильная ленивая инициализация рефа. Объект будет проинициализирован только при доступе к полю current.
https://thoughtspile.github.io/2021/11/30/lazy-useref/
Владимир Клепов поделился техникой создания ленивой инициализации хука useRef. В отличие от useState, хук useRef не принимает функцию для инициализации значения. Ленивая инициализация может улучшить производительность компонента, т.к. позволяет вычислить значение рефа в момент его использования, а не при рендере компонента.
Есть несколько подходов к реализации данной техники:
- Установка значения рефа в useEffect. Минус в том, что значение рефа не будет доступно в первый рендер, в useLayoutEffect, а также в дочерних useEffect.
- Кастомный хук с инициализацией на месте. Минус подхода в том, что функция инициализации выполняется даже если значение рефа было не нужно. Также инициализация блокирует первый рендер.
const none = {};
function useLazyRef(init) {
const ref = useRef(none);
if (ref.current === none) {
ref.current = init();
}
return ref;
}
- Использовать useState. Хук можно использовать как реф если игнорировать функцию обновления. В этом случае, в хуке будет записана ссылка на один объект, и его изменение не будет вызывать ререндер.
const ref = useState(() => ({ current: init() }))[0];
- Создать кастомный хук с полями аксессорами (accessor properties). Если у объекта задать геттер и сеттер на поле current и внутри использовать реф, то получится правильная ленивая инициализация рефа. Объект будет проинициализирован только при доступе к полю current.
https://thoughtspile.github.io/2021/11/30/lazy-useref/
Vladimir Klepov as a Coder
Make useRef lazy — 4 ways
👍2
Обзор React 18
Нашел в ютубе отличное видео, где просто и понятно рассказывают про нововведения в React 18. Советую к просмотру, если еще ничего не знаете про React 18:
https://www.youtube.com/watch?v=2WjpGeTKqyE
Нашел в ютубе отличное видео, где просто и понятно рассказывают про нововведения в React 18. Советую к просмотру, если еще ничего не знаете про React 18:
https://www.youtube.com/watch?v=2WjpGeTKqyE
YouTube
О дивный новый Реакт 18! Что нас ждет?
В новой версии любимого фреймворка появятся не просто фичи, а целая новая философия! Пора нам с вами проникнуться ей!
0:00 Пролог
00:16 Публичный Реакт
00:44 Автоматический батчинг
04:17 Конкурентный режим
08:50 Новинки SSR
12:08 Продвинутый…
0:00 Пролог
00:16 Публичный Реакт
00:44 Автоматический батчинг
04:17 Конкурентный режим
08:50 Новинки SSR
12:08 Продвинутый…
Итоги 2021 года
Подготовил список наиболее интересных событий и статей за текущий год на канале для чтения на новогодних праздниках:
- Релиз фреймворка Remix в open source.
- Адди Османи и Лидия Холли представили проект с примерами использования паттернов проектирования patterns.dev.
- Вышла новая версия React Router 6.0.
- Прошла конференция React Conf 2021 (реплей).
- React 18 перешел в статус бета.
- Вышла новая мажорная версия Create React App 5.0.
- Опасности гидратации в React - читать.
- Гайд по разработке React приложений - читать.
- Как работает обработка ошибок в React - читать.
Всех с наступающим 2022 годом! 🎅☃️🎁
Подготовил список наиболее интересных событий и статей за текущий год на канале для чтения на новогодних праздниках:
- Релиз фреймворка Remix в open source.
- Адди Османи и Лидия Холли представили проект с примерами использования паттернов проектирования patterns.dev.
- Вышла новая версия React Router 6.0.
- Прошла конференция React Conf 2021 (реплей).
- React 18 перешел в статус бета.
- Вышла новая мажорная версия Create React App 5.0.
- Опасности гидратации в React - читать.
- Гайд по разработке React приложений - читать.
- Как работает обработка ошибок в React - читать.
Всех с наступающим 2022 годом! 🎅☃️🎁
👍5
Использование React Server Components в Next.js 12
React Server Components (RSC) – это компоненты, которые выполняются на сервере, и на клиент передается уже отрендеренный компонент в формате JSON.
Рассмотрим основные особенности серверных компонентов. RSC не увеличивает размер бандла приложения, т.к. выполняются только на сервере. Компонент имеет доступ к бэкенду и базе данных. В серверных компонентах нельзя использовать состояние и эффекты, поэтому не поддерживаются хуки useState, useEffect и т.д.
Попробовать RSC пока что можно только вместе с каким-нибудь фреймворком, например, Next.js 12. В настройках конфига Next.js нужно включить экспериментальные фичи для поддержки конкурентного режима и серверных компонентов:
Серверные компоненты могут быть полезны при загрузке большого количества данных. Все запросы будут выполняться на сервере, а на клиенте будет только один запрос на получение RSC, что позволяет избежать больших водопадов загрузки в браузере.
В серверных компонентах использование Suspense позволяет не ждать загрузки всех данных для ответа клиенту. Suspense создает “слоты” в возвращаемом JSON. При получении данных и рендере компонентов внутри Suspense, сервер стримит JSON новых компонентов клиенту, который вставляет их в нужные слоты.
Не стоит путать серверные компоненты и техники пререндера контента, такие как Server-side rendering (SSR) или Static site generation (SSG). RSC позволяет отрендерить на сервере только часть компонентов на странице, а не всю страницу целиком.
https://blog.logrocket.com/react-server-components-nextjs-12/
демка: https://next-news-rsc.vercel.sh/ (github)
React Server Components (RSC) – это компоненты, которые выполняются на сервере, и на клиент передается уже отрендеренный компонент в формате JSON.
Рассмотрим основные особенности серверных компонентов. RSC не увеличивает размер бандла приложения, т.к. выполняются только на сервере. Компонент имеет доступ к бэкенду и базе данных. В серверных компонентах нельзя использовать состояние и эффекты, поэтому не поддерживаются хуки useState, useEffect и т.д.
Попробовать RSC пока что можно только вместе с каким-нибудь фреймворком, например, Next.js 12. В настройках конфига Next.js нужно включить экспериментальные фичи для поддержки конкурентного режима и серверных компонентов:
// next.config.js
module.exports = {
experimental: {
concurrentFeatures: true,
serverComponents: true,
},
}
Серверные компоненты могут быть полезны при загрузке большого количества данных. Все запросы будут выполняться на сервере, а на клиенте будет только один запрос на получение RSC, что позволяет избежать больших водопадов загрузки в браузере.
В серверных компонентах использование Suspense позволяет не ждать загрузки всех данных для ответа клиенту. Suspense создает “слоты” в возвращаемом JSON. При получении данных и рендере компонентов внутри Suspense, сервер стримит JSON новых компонентов клиенту, который вставляет их в нужные слоты.
Не стоит путать серверные компоненты и техники пререндера контента, такие как Server-side rendering (SSR) или Static site generation (SSG). RSC позволяет отрендерить на сервере только часть компонентов на странице, а не всю страницу целиком.
https://blog.logrocket.com/react-server-components-nextjs-12/
демка: https://next-news-rsc.vercel.sh/ (github)
LogRocket Blog
React Server Components in Next.js 13 - LogRocket Blog
Next.js 13 provides better support for React Server Components, which result in components with zero bundle size and improved load times.
🔥10
Современные сборщики 2022
Собрал небольшую коллекцию инструментов-сборщиков, к которым стоит обратить внимание в 2022 году.
SWC – swc.rs
Предназначен для минификации, бандлинга и компиляции исходного кода веб-приложения.
Используется в Next.js 12, Parcel 2 и Deno. В Next.js заменяет Babel для бандлинга и Terser для минификации. В приложениях сборка ускорилась в 5 раз, а fast refresh в 3 раза. Компиляция кода в 17 раз быстрее чем Babel. Написан на Rust.
Поддерживает из коробки TypeScript, React.
Есть возможность интеграции в webpack для компиляции кода через swc-loader. Пример.
Vite – vitejs.dev
Использует Rollup для сборки приложений и esbuild для предварительной сборки зависимостей. В Vite очень быстро работает dev-сервер и HMR. В dev режиме Vite не собирает бандл, а использует нативные ES модули. Есть готовые плагины для интеграции с React. Поддерживает TypeScript из коробки. Пример.
Rome – rome.tools
Швейцарский нож в сфере веб-разработки. Из коробки должен будет уметь бандлить, форматировать, компилировать, минифицировать, тестировать и т.д. Также будет поддержка TypeScript и React.
Проект изначально делался на TypeScript, но после был полностью переписан на Rust. Пока что частично работает только линтинг.
esbuild – esbuild.github.io
Супер быстрый сборщик, написанный на Go. Из коробки поддерживает TypeScript и React, умеет делать минификацию. Есть возможность запуска dev-сервера:
Собрал небольшую коллекцию инструментов-сборщиков, к которым стоит обратить внимание в 2022 году.
SWC – swc.rs
Предназначен для минификации, бандлинга и компиляции исходного кода веб-приложения.
Используется в Next.js 12, Parcel 2 и Deno. В Next.js заменяет Babel для бандлинга и Terser для минификации. В приложениях сборка ускорилась в 5 раз, а fast refresh в 3 раза. Компиляция кода в 17 раз быстрее чем Babel. Написан на Rust.
Поддерживает из коробки TypeScript, React.
Есть возможность интеграции в webpack для компиляции кода через swc-loader. Пример.
Vite – vitejs.dev
Использует Rollup для сборки приложений и esbuild для предварительной сборки зависимостей. В Vite очень быстро работает dev-сервер и HMR. В dev режиме Vite не собирает бандл, а использует нативные ES модули. Есть готовые плагины для интеграции с React. Поддерживает TypeScript из коробки. Пример.
Rome – rome.tools
Швейцарский нож в сфере веб-разработки. Из коробки должен будет уметь бандлить, форматировать, компилировать, минифицировать, тестировать и т.д. Также будет поддержка TypeScript и React.
Проект изначально делался на TypeScript, но после был полностью переписан на Rust. Пока что частично работает только линтинг.
esbuild – esbuild.github.io
Супер быстрый сборщик, написанный на Go. Из коробки поддерживает TypeScript и React, умеет делать минификацию. Есть возможность запуска dev-сервера:
esbuild --bundle src/index.js --outfile=www/main.js --servedir=www👍14🔥2
Blitz – фулстек фреймворк для React
Фреймворк Blitz сделан на базе Next.js, его ключевой особенностью является подход “Zero API”. Этот подход добавляет абстрактный слой работы с данными, позволяя избавиться от работы с REST или GraphQL. При разработке компонентов можно напрямую вызывать функции бэкенда. Во время сборки эти вызовы будут заменены на HTTP запросы к API, а само API будет сгенерировано автоматически.
Этот подход хорошо сочетается с TypeScript. При передаче параметров в функцию бэкенда будет происходить автоматическая проверка типов.
Функции бэкенда можно использовать по разному. В них можно вызывать напрямую изменения в БД, реализовать BFF, либо делать какие-то вычисления. По умолчанию для работы с БД предустановлена Prisma. Из коробки реализована поддержка авторизации пользователя по имейл/паролю.
https://blitzjs.com/
Фреймворк Blitz сделан на базе Next.js, его ключевой особенностью является подход “Zero API”. Этот подход добавляет абстрактный слой работы с данными, позволяя избавиться от работы с REST или GraphQL. При разработке компонентов можно напрямую вызывать функции бэкенда. Во время сборки эти вызовы будут заменены на HTTP запросы к API, а само API будет сгенерировано автоматически.
Этот подход хорошо сочетается с TypeScript. При передаче параметров в функцию бэкенда будет происходить автоматическая проверка типов.
Функции бэкенда можно использовать по разному. В них можно вызывать напрямую изменения в БД, реализовать BFF, либо делать какие-то вычисления. По умолчанию для работы с БД предустановлена Prisma. Из коробки реализована поддержка авторизации пользователя по имейл/паролю.
https://blitzjs.com/
Blitzjs
Blitz.js - The Missing Fullstack Toolkit for Next.js
Blitz picks up where Next.js leaves off, providing battle-tested libraries and conventions for shipping and scaling world wide applications.
👎2🔥2
tRPC – замена REST и GraphQL
Заметил в Blitz интересный подход по работе с API и обнаружил библиотеку tRPC, которая делает точно так же, но не привязана к конкретному фреймворку.
Библиотека реализует технологию RPC по передаче данных. Все запросы делятся на получение и изменение данных и отправляются на один URL. Ответ на запрос приходит в формате JSON, из которого можно получить состояние ответа, сообщение об ошибке и данные. Если одновременно необходимо отправить несколько запросов, то их можно забатчить – объединить в один.
Главная особенность tRPC в том, что при написании типов параметров и ответов на сервере их можно использовать на клиенте. Делается это импортом типов, поэтому в клиентский бандл серверная часть кода не попадает.
Для React в tRPC есть готовые хуки useQuery и useMutation для получения и изменения данных. Также есть готовый плагин для Next.js для поддержки SSR и SSG.
https://trpc.io/
Заметил в Blitz интересный подход по работе с API и обнаружил библиотеку tRPC, которая делает точно так же, но не привязана к конкретному фреймворку.
Библиотека реализует технологию RPC по передаче данных. Все запросы делятся на получение и изменение данных и отправляются на один URL. Ответ на запрос приходит в формате JSON, из которого можно получить состояние ответа, сообщение об ошибке и данные. Если одновременно необходимо отправить несколько запросов, то их можно забатчить – объединить в один.
Главная особенность tRPC в том, что при написании типов параметров и ответов на сервере их можно использовать на клиенте. Делается это импортом типов, поэтому в клиентский бандл серверная часть кода не попадает.
Для React в tRPC есть готовые хуки useQuery и useMutation для получения и изменения данных. Также есть готовый плагин для Next.js для поддержки SSR и SSG.
// server/index.ts
import * as trpc from '@trpc/server';
import { z } from 'zod';
const appRouter = trpc
.router()
.query('getUser', {
input: (val: unknown) => {
if (typeof val === 'string') return val;
throw new Error(`Invalid input: ${typeof val}`);
},
async resolve(req) {
req.input; // string
return { id: req.input, name: 'Bilbo' };
},
})
.mutation('createUser', {
// validate input with Zod
input: z.object({ name: z.string().min(5) }),
async resolve(req) {
// use your ORM of choice
return await UserModel.create({
data: req.input,
});
},
});
export type AppRouter = typeof appRouter;
https://trpc.io/
trpc.io
tRPC - Move Fast and Break Nothing.
End-to-end typesafe APIs made easy. | tRPC
End-to-end typesafe APIs made easy. | tRPC
End-to-end typesafe APIs made easy. Automatic typesafety & autocompletion inferred from your API-paths, their input data, & outputs 🧙♂️
👍7🔥4👎2
Обзор React Router v6
Тайлер МакГиннис написал подробный обзор про React Router v6.
React Router используется в 44% проектах в React. Проблема в том, что не все готовы уделить время на изучение того, как работает React Router. Поэтому МакГиннис собрал в одной статье основную информацию для базового понимания роутера.
В обзоре разобрана верхнеуровневая структура роутера. Какие в нем есть API и компоненты, и для чего они используются. Разобраны основные сценарии использования роутера: рендер сайдбара, кастомизация ссылки, защищенные роуты, использование конфига роутера.
https://ui.dev/react-router-tutorial/
Тайлер МакГиннис написал подробный обзор про React Router v6.
React Router используется в 44% проектах в React. Проблема в том, что не все готовы уделить время на изучение того, как работает React Router. Поэтому МакГиннис собрал в одной статье основную информацию для базового понимания роутера.
В обзоре разобрана верхнеуровневая структура роутера. Какие в нем есть API и компоненты, и для чего они используются. Разобраны основные сценарии использования роутера: рендер сайдбара, кастомизация ссылки, защищенные роуты, использование конфига роутера.
https://ui.dev/react-router-tutorial/
👍6👎2
Решаем проблему проп дриллинга
Проп дриллинг – это анти-паттерн, при котором передача пропсов компоненту происходит через промежуточные компоненты, которые не используют получаемые пропсы, а только передают их в следующие компоненты.
Самый простой способ решить проблему проп дриллинга – использование контекста. Однако, при использовании контекста может возникнуть несколько проблем. Одна из них – это проблема переиспользования компонентов. Компонент, в котором используется контекст, зависит от значения контекста. Это означает, что если использовать компонент вне контекста или передать в контекст неправильное значение, то будет ошибка. Еще одна из проблем использования контекста – производительность. Изменение значения в провайдере будет провоцировать ререндер дочерних компонентов провайдера.
Другим подходом к решению проблемы проп дриллинга является композиция компонентов. Использование композиции компонентов позволяет поднять компонент до корневого и использовать его внутри родительского компонента вместо передачи данных во вложенный компонент.
https://blog.logrocket.com/solving-prop-drilling-react-apps/#container-components
Проп дриллинг – это анти-паттерн, при котором передача пропсов компоненту происходит через промежуточные компоненты, которые не используют получаемые пропсы, а только передают их в следующие компоненты.
Самый простой способ решить проблему проп дриллинга – использование контекста. Однако, при использовании контекста может возникнуть несколько проблем. Одна из них – это проблема переиспользования компонентов. Компонент, в котором используется контекст, зависит от значения контекста. Это означает, что если использовать компонент вне контекста или передать в контекст неправильное значение, то будет ошибка. Еще одна из проблем использования контекста – производительность. Изменение значения в провайдере будет провоцировать ререндер дочерних компонентов провайдера.
Другим подходом к решению проблемы проп дриллинга является композиция компонентов. Использование композиции компонентов позволяет поднять компонент до корневого и использовать его внутри родительского компонента вместо передачи данных во вложенный компонент.
function App() {
const [data, setData] = useState("some state");
return (
<ParentComponent>
<ComponentOne>
<ComponentTwo data={data} />
</ComponentOne>
</ParentComponent>
);
}
https://blog.logrocket.com/solving-prop-drilling-react-apps/#container-components
LogRocket Blog
A better way of solving prop drilling in React apps - LogRocket Blog
In the spirit of "using the platform," learn how the React library provides a workaround for prop drilling without Redux or the Context API.
👍8
Хочу провести небольшой опрос по инструментам тестирования на React проектах:
Какой test runner используете на проекте для юнит и интеграционного тестирования?
Anonymous Poll
75%
Jest
5%
Mocha
3%
Ava
2%
Jasmine
6%
Другое
20%
Не пишет тесты
Какие библиотеки для тестирования используете на проекте?
Anonymous Poll
54%
Testing Library
15%
Enzyme
30%
Cypress
11%
Playwright
10%
Selenium
13%
Puppeteer
15%
Другое
👍2
Условные выражения в JSX
Владимир Клепов в своем блоге поделился советами по работе с условными выражениями в JSX. Использование условных выражений в JSX может привести к неожиданным результатам, если не учитывать особенности работы логических операторов.
- Рендеринг по числовому условию. Конструкция вида
- Условное И (&&) имеет больший приоритет, поэтому в конструкциях где имеются И (&&) и ИЛИ (||) используйте скобки для определения приоритета. Например:
- Не зацикливайтесь на тернарных операторах. Если есть вложенные тернарные операторы, то это плохой знак. Вместо вложенных тернарных операторов попробуйте использовать логическое И (&&) или функцию с if/else:
Код выше можно заменить на функцию:
- Будьте аккуратны с props.children в условиях. В props.children может быть пустой массив, фрагмент, одиночный элемент. Поэтому условие
- Одинаковые элементы будут обновляться. Например, код
https://thoughtspile.github.io/2022/01/17/jsx-conditionals/
Владимир Клепов в своем блоге поделился советами по работе с условными выражениями в JSX. Использование условных выражений в JSX может привести к неожиданным результатам, если не учитывать особенности работы логических операторов.
- Рендеринг по числовому условию. Конструкция вида
{gallery.length && <Gallery slides={gallery}>} может отрендерить в DOM число 0. Если gallery.length будет равен 0, то оно как falsy значение будет сразу возвращено из конструкции &&. Чтобы исправить проблему, можно использовать тернарный оператор: {gallery.length ? <Gallery slides={gallery} /> : null}.- Условное И (&&) имеет больший приоритет, поэтому в конструкциях где имеются И (&&) и ИЛИ (||) используйте скобки для определения приоритета. Например:
{cond1 || cond2 && <JSX />} тоже самое что и {cond1 || (cond2 && <JSX />)}, поэтому пишите явно {(cond1 || cond2) && <JSX />}.- Не зацикливайтесь на тернарных операторах. Если есть вложенные тернарные операторы, то это плохой знак. Вместо вложенных тернарных операторов попробуйте использовать логическое И (&&) или функцию с if/else:
{isEmoji
? <EmojiButton />
: isCoupon
? <CouponButton />
: isLoaded && <ShareButton />}
Код выше можно заменить на функцию:
const getButton = () => {
if (isEmoji) return <EmojiButton />;
if (isCoupon) return <CouponButton />;
return isLoaded ? <ShareButton /> : null;
};
- Будьте аккуратны с props.children в условиях. В props.children может быть пустой массив, фрагмент, одиночный элемент. Поэтому условие
{props.children && <div>{props.children}</div>} может привести к багам.- Одинаковые элементы будут обновляться. Например, код
{hasItem ? <Item id={1} /> : <Item id={2} />} будет эквивалентен коду <Item id={hasItem ? 1 : 2} />. Это значит, что при изменении hasItem компонент Item не будет размонтироваться и монтироваться заново, вместо этого будет обновление пропсов.https://thoughtspile.github.io/2022/01/17/jsx-conditionals/
👍15
Forwarded from Defront — про фронтенд-разработку и не только (Alexander Myshov)
React server components под капотом
Чан Ву рассказал про внутреннее устройство React server components (RSC) — "How React server components work: an in-depth guide".
Серверные компоненты — это экспериментальный тип React-компонентов, которые не попадают в клиентский бандл и позволяют бесшовно выносить на сервер часть логики приложения. Результатом выполнения серверных компонентов является представление дерева React-компонентов в формате, подходящем для стриминга. В статье подробно разбирается принцип работы RSC, их ограничения и внутреннее устройство.
Статья хорошая. Рекомендую почитать всем, кто хочет разобраться в устройстве серверных компонентов.
#react #internals
https://blog.plasmic.app/posts/how-react-server-components-work/
Чан Ву рассказал про внутреннее устройство React server components (RSC) — "How React server components work: an in-depth guide".
Серверные компоненты — это экспериментальный тип React-компонентов, которые не попадают в клиентский бандл и позволяют бесшовно выносить на сервер часть логики приложения. Результатом выполнения серверных компонентов является представление дерева React-компонентов в формате, подходящем для стриминга. В статье подробно разбирается принцип работы RSC, их ограничения и внутреннее устройство.
Статья хорошая. Рекомендую почитать всем, кто хочет разобраться в устройстве серверных компонентов.
#react #internals
https://blog.plasmic.app/posts/how-react-server-components-work/
Plasmic Blog
How React server components work: an in-depth guide
A deep dive exploration of React server components under the hood.
👍3
Исправление ошибок гидратации
Бен Илегбоду рассказывает, как исправить проблемы гидратации в React приложениях.
При различиях рендера на сервере и клиенте, React сообщает об этом, выдавая предупреждение в консоль. Если есть различия в атрибутах элемента, то при гидратации React оставит текущие значения атрибутов, полученных от сервера. Это значит, что UI окажется устаревшим. Например, такая проблема может возникнуть с именами классов у элементов, если они генерируются по определенному условию.
Один из способов решения подобных проблем – использование эффектов, о котором подробно рассказал Бен Илегбод в своей статье.
https://www.benmvp.com/blog/handling-react-server-mismatch-error/
Бен Илегбоду рассказывает, как исправить проблемы гидратации в React приложениях.
При различиях рендера на сервере и клиенте, React сообщает об этом, выдавая предупреждение в консоль. Если есть различия в атрибутах элемента, то при гидратации React оставит текущие значения атрибутов, полученных от сервера. Это значит, что UI окажется устаревшим. Например, такая проблема может возникнуть с именами классов у элементов, если они генерируются по определенному условию.
Один из способов решения подобных проблем – использование эффектов, о котором подробно рассказал Бен Илегбод в своей статье.
https://www.benmvp.com/blog/handling-react-server-mismatch-error/
Ben Ilegbodu
Handling the React server hydration mismatch error | Ben Ilegbodu
How to resolve the server mismatch error when hydrating a shared React component that can be used in client-side only or server-side rendered apps
👍5
Проблемы в типизации children
Рассмотрим пример компонента:
Со стороны TypeScript в данном коде нет ошибок, компонент скомпилируется. Но при запуске приложения будет ошибка со стороны React:
Проблема в том, что неверно написаны типы для React.ReactNode. Если посмотреть в исходники типов, то можно увидеть, что ReactNode расширяется от ReactFragment, который разрешает использование объекта {}.
При разработке компонентов, которые принимают children, стоит учитывать ошибку в типах React. Вариант решения проблемы – создать свой тип ReactNode, который не допускает использование объекта.
https://fettblog.eu/react-types-for-children-are-broken/
Рассмотрим пример компонента:
const Card: React.FC = props => { ... }
export default function App() {
const randomObject = {};
return (
<div className="App">
<Card>{randomObject}</Card>
</div>
);
}
Со стороны TypeScript в данном коде нет ошибок, компонент скомпилируется. Но при запуске приложения будет ошибка со стороны React:
Objects are not valid as a React child (found: object with keys {}).Проблема в том, что неверно написаны типы для React.ReactNode. Если посмотреть в исходники типов, то можно увидеть, что ReactNode расширяется от ReactFragment, который разрешает использование объекта {}.
interface ReactNodeArray extends Array<ReactNode> {}
type ReactFragment = {} | ReactNodeArray;
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
При разработке компонентов, которые принимают children, стоит учитывать ошибку в типах React. Вариант решения проблемы – создать свой тип ReactNode, который не допускает использование объекта.
https://fettblog.eu/react-types-for-children-are-broken/
fettblog.eu
TypeScript + React: Children types are broken
Update April 2022: With the update to React 18, a lot of those problems have been fixed. See this pull request for more details
👍8
Лучшие практики React Testing Library
Бен Илегбоду делится лучшими практиками при работе с библиотекой для тестирования Testing Library. Кратко о них:
- Используйте user-event вместо fireEvent для взаимодействия с элементами в компоненте. Библиотека Testing Library экспортирует fireEvent, но её API более низкоуровневое. Гораздо проще и читабельнее будет использование user-event.
- Избегайте прямых запросов в DOM. Вместо querySelector используйте запросы получения элементов в зависимости от их роли, содержимого текста, лейбла и т.д.
- Используйте screen вместо деструктуризации render. Эта практика избавит от постоянного изменения объекта деструктуризации по мере добавления или удаления нужных нам запросов.
- Правильно используйте waitFor. Не кладите в колбек waitFor вызовы функций сайд-эффектов, например, клик по кнопке или ввод текста. Внутри waitFor должно быть только утверждение (expect). Связано это с тем, что waitFor вызывает функцию колбека несколько раз, пока утверждение внутри него не станет верным или закончится время на проверку.
Большинство случаев поддержки лучших практик можно добиться установкой правил ESLint для Testing Library, например, eslint-plugin-testing-library.
https://www.benmvp.com/blog/react-testing-library-best-practices/
Бен Илегбоду делится лучшими практиками при работе с библиотекой для тестирования Testing Library. Кратко о них:
- Используйте user-event вместо fireEvent для взаимодействия с элементами в компоненте. Библиотека Testing Library экспортирует fireEvent, но её API более низкоуровневое. Гораздо проще и читабельнее будет использование user-event.
- Избегайте прямых запросов в DOM. Вместо querySelector используйте запросы получения элементов в зависимости от их роли, содержимого текста, лейбла и т.д.
- Используйте screen вместо деструктуризации render. Эта практика избавит от постоянного изменения объекта деструктуризации по мере добавления или удаления нужных нам запросов.
- Правильно используйте waitFor. Не кладите в колбек waitFor вызовы функций сайд-эффектов, например, клик по кнопке или ввод текста. Внутри waitFor должно быть только утверждение (expect). Связано это с тем, что waitFor вызывает функцию колбека несколько раз, пока утверждение внутри него не станет верным или закончится время на проверку.
Большинство случаев поддержки лучших практик можно добиться установкой правил ESLint для Testing Library, например, eslint-plugin-testing-library.
https://www.benmvp.com/blog/react-testing-library-best-practices/
Ben Ilegbodu
React Testing Library best practices | Ben Ilegbodu
5 categories of best practices for testing components with React Testing Library based on the ESLint plugin
👍7
Новая документация React
React запустил бету версию сайта документации beta.reactjs.org. Пока что она в процессе наполнения и не все разделы сайта готовы. Но уже сейчас видно, чем новая документация будет отличаться от старой: будет больше интерактивных примеров, добавятся задачи на понимание принципов работы React. Также во всех примерах и объяснениях будут использоваться хуки, а не классы.
https://beta.reactjs.org/
React запустил бету версию сайта документации beta.reactjs.org. Пока что она в процессе наполнения и не все разделы сайта готовы. Но уже сейчас видно, чем новая документация будет отличаться от старой: будет больше интерактивных примеров, добавятся задачи на понимание принципов работы React. Также во всех примерах и объяснениях будут использоваться хуки, а не классы.
https://beta.reactjs.org/
react.dev
React is the library for web and native user interfaces. Build user interfaces out of individual pieces called components written in JavaScript. React is designed to let you seamlessly combine components written by independent people, teams, and organizations.
👍16👎1