Заметки про React – Telegram
Заметки про React
3.78K subscribers
34 photos
8 videos
485 links
Короткие заметки про React.js, TypeScript и все что с ним связано
Download Telegram
TanStack Router

Таннер Линсли представил новый проект – TanStack Router. Это масштабируемый роутер для приложений, написанный на TypeScript и не привязанный к конкретному фреймворку.

Автор предлагает сразу много фич из коробки:
- Управление стейтом из URL
- Встроенное кэширование
- Валидация схемы search params
- Автоматический prefetch запросов
- Лоадеры данных на уровне роута
- Code-Splitting

Для создания роутера приложения не требуется JSX, все роуты объявляются через функции. Библиотека находится в статусе беты и пока что есть адаптер только для React.

https://tanstack.com/router/v1
👍12
Forwarded from Сова пишет…
На волне очень приятных эмоций от общения на дискусии, я закончил оформлять подборку статей!

Как проектировать API, что особенного в подборе цветов для веб-сайта, как работает движок V8?

https://news.sova.dev/issues/19-1263486
👍4
Монорепозиторий c Turborepo

Гайд по созданию и настройке для проекта монорепозитория со следующим стеком:
- npm для установки зависимостей и линковки пакетов;
- turborepo для оркестрации задач;
- tsc, postcss-cli и vite для сборки пакетов;
- ladle для демо-стенда;

Такой стек удобен тем, что в нем можно поменять инструмент на любой другой.

Одно из преимуществ Turborepo – кэширование результатов сборки. При автоматизированной сборке на CI кэширование может значительно увеличить скорость работы пайплайнов.

https://habr.com/ru/post/694808/
👍4
Создание форм из JSON схемы

uniforms – библиотека для генерации форм на основе JSON схемы. Структура схемы и валидация может быть любой. Подключение схемы к форме происходит через адаптер. В документации uniforms рекомендуют работать с ajv, наиболее популярной библиотекой для валидации JSON схемы.

Преимущества uniforms:
- автоматическая генерация формы;
- встроенный набор компонентов для отображения любых типов полей;
- создание кастомных полей;
- асинхронная валидация формы;
- поддержка кастомных тем для стилизации;

Пример кода для генерации формы:

import { AutoForm } from "uniforms"
import { createBridge } from "./createBridge" // explained later

function AutomaticForm() {
return <AutoForm schema={createBridge(loginSchema)} />;
}


https://uniforms.tools/
Гайд https://www.vazco.eu/blog/a-novel-schema-first-approach-to-building-forms
👍5👎1
Как работает Framer Motion

Нанда Шахрасяд рассказал, как работает анимация в Framer Motion.

Чтобы сделать плавное изменение CSS свойств между двумя состояниями, используется свойство transition. С его помощью плавно изменяется width, height, transform и другие свойства, но не все. У этого способа есть недостатки:
- Изменение размеров макета у элемента считается менее производительным, чем использование transform.
- Нельзя сделать плавное изменение таких свойств как justify-content, потому что justify-content не анимированное свойство.

Для анимации изменения размеров макета и перемещения, в Framer Motion используется техника FLIP (First, Last, Inverse, Play). При рендере элемента в реф сохраняется его текущее расположение. Если текущее расположение отличается от предыдущего, то вычисляется дельта. Элементу устанавливается стиль transform с полученной дельтой (происходит инверсия) и запускается анимация transform к текущему расположению. Пример анимации изменения позиции:

export default function Motion() {
const squareRef = React.useRef();
const initialPositionRef = React.useRef();

React.useLayoutEffect(() => {
const box = squareRef.current?.getBoundingClientRect();
if (moved(initialPositionRef.current, box)) {
const deltaX = initialPositionRef.current.x - box.x;
const deltaY = initialPositionRef.current.y - box.y;

squareRef.current.style.transform = `translate(${deltaX}px, ${deltaY}px)`;

// animate back to the final position
animate({
…params,
onUpdate: progress => {
squareRef.current.style.transform =
translate(${deltaX * progress}px, ${deltaY * progress}px);
}
})
}
initialPositionRef.current = box;
});

return <div id="motion" ref={squareRef} />;
}


https://www.nan.fyi/magic-motion
👍8
Таймлайн компонента в React

Джулс Блом создала диаграмму таймлайна работы компонента с хуками в React. Также можно проверить свои знания по тому, как работает React в небольшом квизе после диаграммы.

Знание порядка вызова хуков может помочь писать компоненты в React правильно и эффективно. Компонент в React - это всего лишь функция, которая возвращает разметку. Хуки дополняют компонент и вызываются в определенном порядке, в соответствии с жизненным циклом компонента.

https://julesblom.com/writing/react-hook-component-timeline
👍12
Доступный drag and drop

React Spectrum зарелизили поддержку drag and drop в React Aria and React Spectrum. Релиз содержит набор хуков для реализации drag and drop с поддержкой мобильных устройств, клавиатуры и screen reader. Особенности:

- Гибкость – хуки включают в себя верхнеуровневое API для основных манипуляцих с элементами: перемещение, изменение порядка, копирование.
- Доступность – поддержка клавиатуры, screen reader, мобильных устройств.
- Совместимость – поддерживает разные форматы данных, используя нативный HTML drag and drop.
- Кастомизация – возможность изменения UI и поведения хуков.


function Draggable() {
let { dragProps, isDragging } = useDrag({
getItems() {
return [{
'text/plain': 'hello world'
}];
}
});

return (
<div
{...dragProps}
role="button"
tabIndex={0}
className={`draggable ${isDragging ? 'dragging' : ''}`}
>
Drag me
</div>
);
}


https://react-spectrum.adobe.com/blog/drag-and-drop.html
👍7👎1
Релиз tRPC v10

После нескольких релиз-кандидатов появилась стабильная мажорная версия tRPC v10.

Основные изменения:
- Улучшенная поддержка TypeScript. Упрощен вывод типов, больше поддержки для IDE. Улучшена производительность для TypeScript.
- Изменена конструкция создания роутера и вызова процедур.
- Мидлвары стали переиспользуемыми.
- Функции процедуры стали переиспользуемыми, и их можно выстраивать в цепочку. Можно сделать публичные и приватные процедуры, добавив мидлвар проверки авторизации.
- Гибкая обработка ошибок: перед отправкой ошибки клиенту есть возможность ее видоизменить.

Если в проекте уже используется tRPC v9, то можно обновиться на v10 поэтапно. После обновления tRPC для роутеров нужно добавить метод interop() и серверный код продолжит работать как раньше.

Пример переиспользуемых процедур:

export const protectedProcedure = t.procedure.use(isAuthed);

export const appRouter = router({
createPost: protectedProcedure.mutation(({ctx}) => {
const session = ctx.session;

// [...]
}),
});


https://trpc.io/blog/announcing-trpc-10
👍5
Использование структур данных в приложениях React

Пример использования основных структур данных в приложениях React от Йоханнес Кеттманн. Большинство разработчиков не используют структуры данных явно и не видят причин их использовать в JavaScript фреймворках. Для этого есть свои причины: в JavaScript не реализовано большинство структур данных, и React плохо работает с кастомными структурами данных.

Знать структуры данных полезно. Неправильный выбор структуры данных может привести к беспорядочному коду. В статье автор собрал примеры использования в приложениях на React таких структур данных, как Map, Set, Stack, Queue и Tree.

https://profy.dev/article/javanoscript-data-structures
👍8
Улучшаем время взаимодействия в React в 4 раза

Практический гайд от инженеров Causal и Ивана Акулова по улучшению производительности React приложения. Уменьшив количество ре-рендеров компонентов, инженеры смогли добиться увеличения скорости работы компонентов в 4 раза. Для определения проблемных мест приложения использовалось профилирование во вкладке Performance и React Profiler. В гайде много скриншотов и видео, а также примеров кода.

https://www.causal.app/blog/react-perf
👍13
Оценка покрытия кода со Storybook test runner

Инструменты оценки покрытия кода тестами позволяют выявить непроверенные пограничные случаи. Это помогает писать более полные тесты и быть уверенным в надежности компонентов. В Storybook для запуска тестов используется Jest, а для описания кейсов Playwright.

С помощью Storybook test runner можно генерировать отчеты покрытия кода. Для генерации отчетов используется библиотека Istanbul. Чтобы использовать Istanbul необходимо установить аддон @storybook/addon-coverage. В гайде описаны шаги установки, а также варианты оформления отчетов.

https://storybook.js.org/blog/code-coverage-with-the-storybook-test-runner/
👍5
Архитектура React Query

Доминик Дорфмайстер подготовил верхнеуровневое устройство библиотеки React Query. Из-за внутреннего устройства библиотеки её легко адаптировать под любой фреймворк. Адаптеры для React и Solid занимают не больше 100 строк кода.

Все начинается с QueryClient, который используется во всем приложении. Это контейнер для кэша QueryCache и MutationCache. Кэш хранит запросы – объекты Query. Объект Query хранит в себе информацию о запросе, выполняет сам запрос, делает отмену и дедупликацию.

При использовании хука useQuery создается Observer. Это промежуточный объект между Query и компонентом React. Он информирует компонент о необходимости ре-рендера при изменении состояния запроса Query.

https://tkdodo.eu/blog/inside-react-query
👍11
Nextra 2.0

Nextra – это инструмент, облегчающий разработку документации сайта, основанный на Next.js и разрабатываемый командой Vercel.

Новый релиз 2.0 включает в себя редизайн и новые фичи: MDX 2, поддержка Tailwind, встроенный поиск FlexSearch, i18n, доступность A11Y, подсветка кода.

Использование Next.js позволяет организовать роутинг страниц на основе структуры проекта. Также можно создавать как динамические страницы (SSR), так и генерировать статические страницы.

С помощью Nextra созданы сайты документаций для проектов Turbo, SWR и других проектов Vercel.

https://nextra.site/
👍5
Гексагональная архитектура в React

Основная идея в гексагональной архитектуре, чистой архитектуре и других похожих парадигмах заключается в концепции разделения слоев и выделении отдельного доменного слоя. При обсуждении применения гексагональной архитектуры для приложения React возникает вопрос о правильном применении.

Алекс Кондов рассказал о подходе к разработке приложений на React с применением гексагональной архитектуры. Для доступа к доменной логике в компонентах используются хуки. Хуки – это адаптеры между React и вашим доменным кодом. Под доменным кодом имеются в виду запросы в API, управление пользователем или любой другой бизнес-сущностью. Сама доменная логика может быть реализована с помощью любой удобной парадигмой программирования. В качестве примера можно посмотреть на react-query. Эта библиотека написана с помощью ООП и использует хуки как адаптер к React.

function PostPage({ postId }) {
const { post, error, bookmarkPost, reactToPost } = usePost(postId);

// --snip--
}

function usePost(postId) {
const [post, setPost] = useState(null);
// --snip--

const getPost = () => {
client.getPost(postId).then(setPost).catch(setError)
}

const bookmarkPost = () => {
client.bookmarkPost(postId, userId);
};

useEffect(() => {
getPost()
}, [])

// --snip--

return {
post: mapToDomainObject(post),
bookmarkPost,
// --snip--
};
}


https://alexkondov.com/hexagonal-inspired-architecture-in-react/
👍7👎7
Релиз Vite 4.0

Вышла новая версия Vite 4.0. Основные изменения:

• Используется Rollup 3.
• Новый плагин для сборки @vitejs/plugin-react-swc. Он использует esbuild для сборки приложения и SWC вместо Babel во время разработки.
• Современная сборка по умолчанию нацелена на safari14 вместо safari13. Если нужна поддержка старых браузеров, то используйте @vitejs/plugin-legacy.
• Кодировка сборки по умолчанию utf8.
• Для импорта CSS как строки используйте суффикс ?inline: import stuff from './global.css?inline’.

https://vitejs.dev/blog/announcing-vite4.html
👍5
Плохие практики использования useState

Хук useState используется чаще всего при работе с React. Есть несколько плохих практик при работе с ним, которые приводят к более сложному коду, увеличению количества багов и ухудшению производительности компонента.

Йоханнес Кеттманн в блоге Profy собрал список плохих практик использования useState и предложил к каждому свое решение. Кратко про часть из них:

Избыточный стейт. Стейт, который зависит от другой переменной стейта, скорее всего можно безболезненно заменить на производную переменную. Пример избыточного стейта:

const onChangeFirstName = (event) => {
setFirstName(event.target.value);
setFullName(`${event.target.value} ${lastName}`);
};


Дублирование стейта. Проблема появляется, когда одни и те же данные дублируются в нескольких стейтах. Эта проблема указывает на нарушение принципа единого источника правды. Пример дублирования стейта:

function DuplicateState({ items }) {
const [selectedItem, setSelectedItem] = useState();
const onClickItem = (item) => {
setSelectedItem(item);
};
// --snip--
}


При изменении пропса items в selectedItem могут оказаться устаревшие данные. Чтобы избежать обращения к устаревшим данным, вместо selectedItem используйте selectedItemId. А selectedItem будет вычисляться по выбранному id из items.

Обновление стейта в useEffect. При обновлении стейта в useEffect происходит дополнительный рендер. Также бывает сложно вызвать эффект в нужное время. Например, эффект вызывается при инициализации компонента. Поэтому старайтесь избегать обновления стейта в useEffect. Кстати, есть интересный доклад про useEffect от Дэвида Хуршиди. В нем он призывает вообще отказаться от useEffect.

https://profy.dev/article/react-usestate-pitfalls
👍11
Оптимизация веб шрифтов в Next.js 13

При загрузке кастомных веб шрифтов на сайте может возникнуть проблема FOUT (Flash Of Unstyled Text) или FOIT (Flash Of Invisible Text). Из-за FOUT и FOIT может произойти сдвиг макета, который сбивает пользователя с толку.

Эти проблемы происходят из-за того, что пользователю необходимо загружать кастомные веб шрифты перед их рендером на странице. Лидия Холли написала гайд по оптимизации веб-шрифтов, чтобы минимизировать возможные проблемы загрузки веб шрифтов.

При загрузке кастомного веб шрифта стоит обратить внимание на дескрипторы шрифта. В CSS это свойства size-adjust, ascent-override, descent-override и line-gap-override. Они предназначены для настройки характеристик отображения шрифта. Например, два разных веб шрифта с одинаковым размером шрифта могут занимать разное количество места на странице. При настройке CSS дескрипторов запасного шрифта можно добиться схожести размеров на загружаемый кастомный веб шрифт. Вследствие чего можно избежать сдвига макета.

В Next.js 13 появился новый модуль @next/font. Он позволяет использовать локальные и Google Fonts шрифты, не беспокоясь о деталях оптимизации. При использовании Google Fonts этот модуль скачивает шрифт во время сборки и добавляет запасной шрифт, автоматически добавляя настройки CSS дескриптора:

import { Poppins } from "@next/font/google";

const poppins = Poppins({ weight: "600", subsets: ["latin"] });

export default function Title() {
return <h1 className={poppins.className}>The Acme Blog</h1>;
}


https://www.lydiahallie.io/blog/optimizing-webfonts-in-nextjs-13
🔥10👍41
Применение паттерна Стратегия в React

При разработке React приложения бывает проблема, когда одна часть бизнес-логики реализована по частям в нескольких компонентах, хуках и функциях. У этой проблемы есть название “Стрельба дробью” (Shotgun Surgery). Это запах кода, в котором одно изменение затрагивает сразу несколько классов приложения.

Один из вариантов решения этой проблемы – паттерн Стратегия. В блоге dev.to автор Хьюго Та поделился примером использования паттерна Стратегия при разработке компонента.

В качестве примера – карточки с ценами. Если посетитель из определенной страны, то в карточке указывается цена в валюте его страны и возможная скидка. Для реализации такой бизнес-логики автор создал базовый абстрактный класс и имплементировал классы для разных стран.

abstract class PriceStrategy {
protected country: Country = Country.AMERICA;
protected currency: Currency = Currency.USD;
protected discountRatio = 0;

// --snip--
}

class JapanPriceStrategy extends PriceStrategy {
constructor() {
super();
this.country = Country.JAPAN;
this.currency = Currency.YEN;
this.discountRatio = 0.2;
}

// --snip--
}

<PricingCard price={7669} strategy={new JapanPriceStrategy()} />


https://dev.to/itshugo/applying-design-patterns-in-react-strategy-pattern-enn
👎12👍5
Цветовые форматы в CSS

В CSS есть несколько цветовых форматов: хекскод, rgb(), hsl(), lch() и другие. Самые популярные из них - это хекскод и rgb(). А для чего существуют остальные, и нужно ли их использовать?

В блоге Джошуа Комо вышел гайд по цветовым форматам. В нем он разобрал каждый цветовой формат и его применимость.

https://www.joshwcomeau.com/css/color-formats/
👍2
Переименование экспериментального useEvent в useEffectEvent

В репозитории React смержили ПР, в котором переименовали useEvent в useEffectEvent.

Ранее в устаревшем RFC про useEvent показывали пример использования хука: в эффектах и для оптимизации рендера. Теперь хук будет использоваться только в эффектах. По сообщению Дэна Абрамова оптимизация рендеринга будет прорабатываться отдельно.

Пример использования хука:

const onHappened = useEffectEvent(() => ...);
useEffect(() => {
onHappened();
}, []);


https://github.com/facebook/react/pull/25881
👍5👎4