Заметки про React – Telegram
Заметки про React
3.78K subscribers
34 photos
8 videos
485 links
Короткие заметки про React.js, TypeScript и все что с ним связано
Download Telegram
React, я люблю тебя, но ты сводишь меня с ума

На хабре вышел перевод статьи Франсуа Занинотто с критикой React.

Автор подсвечивает несколько проблем, которые возникают при разработке React приложений:

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

- Контекст. В useContext отсуствует критически важная вещь – возможность реагировать на изменение только определенных полей объекта, как в Redux useSelector. Это приводит к тому, что приходится разделять контекст на более мелкие части.

- useEffect и useCallback. Требует ручного управления зависимостями, заставляя записывать все используемые переменные в список зависимостей. В ​​Solid.js таких проблем нет.

- Строгость хуков. Хуки нельзя вызывать условно. Хоть и известно, что если компонент с хуком нужно показывать по условию, то его нужно вкладывать в промежуточный компонент для предотвращения рендеринга, но все равно, непонятно зачем это нужно делать. Это просто один из примеров сложности хуков.

- Старость фреймворка. React появился в 2013 году и сейчас, при поиске нужной библиотеки для проекта, можно заметить популярные npm пакеты, которые редко обновляются. В основном в них используются классовые компоненты, из-за чего они не очень привлекательны для новых контрибьюторов.

https://habr.com/ru/company/timeweb/blog/693072/
👍8👎5
Полностью типизированные веб-приложения

Кент С. Доддс рассказывает о сквозном покрытии типов в веб-приложениях, от БД до UI через разные границы: localStorage, сеть, БД.

Например, при получении данных из localStorage нельзя точно определить, какие будут получены данные, т.к. со временем они могут измениться. Если кастовать тип для данных из localStorage, то может возникнуть runtime ошибка, например, из-за того, что нет нужного поля в объекте.

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

import { z } from "zod"

const Ticket = z.object({
workshopId: z.string(),
attendeeId: z.string(),
discountCode: z.string().optional()
})
type Ticket = z.infer<typeof Ticket>

const rawTicket = JSON.parse(localStorage.get('ticket'))
const result = Ticket.safeParse(rawTicket);
if (result.success) {
const ticket = result.data
// ^? Ticket
} else {
// result.error will have a handy informative error
}


https://www.epicweb.dev/fully-typed-web-apps
🔥10
Next.js Conf

На этой неделе прошла конференция Next.js Conf, на которой представили Next.js 13 и Turbopack – бандлер и сборщик приложения, написанный на Rust.

В Next.js 13 добавили новую папку для роутинга – /app. В ней можно использовать новые фичи, о которых давно говорили в React.

Layouts.
Позволяет использовать шаблоны для нескольких компонентов. Реализуется через создание файла layout.js.

Server Components.
Next.js начал поддерживать серверные компоненты. Согласно документации все компоненты внутри директории /app являются серверными компонентами по умолчанию. Чтобы обозначить, что компонент является клиентским, нужно в начале файла объявить директиву 'use client';.

Streaming.
Возможность прогрессивного рендера компонентов на странице.

Поддержка async компонентов.
Означает поддержку недавнего RFC о загрузке данных.

Также на конференции рассказали про новый бандлер и сборщик приложения Turbopack. Написан он на Rust, а его главный разработчик – Тобиас Копперс, создатель Webpack. По информации от авторов, Turbopack в 700 раз быстрее Webpack и как минимум в 10 раз быстрее чем Vite. Пока что бандлер находится в альфа-версии.

https://nextjs.org/blog/next-13
🔥5
Пишем свою библиотеку управления состоянием

Джуд Хантер в своем блоге рассказал, как самостоятельно реализовать библиотеку для управления состоянием наподобие Zustand.

Одним из преимуществ библиотек для управления состоянием, в отличие от контекста, является то, что изменение стора не вызывает ререндера всего дерева компонентов. Реализовано это за счет использования селекторов в компоненте.

Чтобы показать свою работу, Джуд Хантер создал функцию создания стора и хук для подписки за изменениями. По аналогии с Zustand при создании стора передаются экшены для изменения стора. Код реализации хука селектора:


const useSelector = <STATE,>(
store: {state: STATE; subscribe: any},
selector: (state: STATE) => any,
) => {
const [selectedValue, setSelectedValue]
= useState(selector(store.state))

useEffect(() => {
return store.subscribe(newState => {
setSelectedValue(
selector(newState);
);
});
}, []);

return selectedValue;
}


https://judehunter.dev/blog/how-to-write-your-own-state-management-library
👍4🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
Интерактивный WebGL в Next.js

Для лендинга конференции Next.js Conf разработчики из Next.js сделали интерактивную фигуру на WebGL и рассказали в своем блоге о процессе создания.

Для реализации WebGL использовали библиотеки react-three-fiber и drei – утилитарная библиотека для react-three-fiber, в которой собраны основные паттерны. Для постпроцессинга используется библиотека @react-three/postprocessing.

https://vercel.com/blog/building-an-interactive-webgl-experience-in-next-js
👍2
Конференция для JavaScript-разработчиков HolyJS 2022 Autumn

🌐 10–11 ноября — онлайн
👥 20 ноября — офлайн в Москве
(с возможностью удаленного участия для тех, кто не готов добраться)

Программа конференции полностью готова

Из интересного про React:
Сергей Константинов, воркшоп «Пишем игру на React и разбираемся с react-reconciler»
Дмитрий Грош, доклад «Батчинг в React»
Константин Астапов, доклад «How to build large react-redux application without code mess»
Сэм Булатов, доклад «Введение в реактивное программирование»

Если вам хочется на несколько часов отвлечься и побыть среди единомышленников, то приходите на HolyJS. А промокод reactnotes2022JRGpc даст скидку 20% на билеты из категории «Для частных лиц».

Подробности и билеты — holyjs.ru
👍3🔥1
React Query: заполняем кэш запросов

В React Query есть поддержка загрузки данных в Suspense, для этого нужно передать параметр suspense: true в настройки запроса. При использовании данного механизма нужно быть осторожным. Если у вас несколько запросов в одном компоненте, то возникает проблема “водопада” запросов. При рендере компонента React Query сообщает, что необходимо выполнить первый запрос, React ставит компонент на паузу и ждет выполнения. После успешного выполнения запроса, компонент перемонтируется заново и React Query сообщает, что необходимо выполнить второй запрос, и сценарий повторяется. Так возникает “водопад” запросов.

Чтобы избежать подобных проблем, Доминик Дорфмайстер в своем блоге поделился способами предварительного заполнения кэша для запросов.

Во-первых, предварительно загружайте данные до рендера компонента. Если проект поддерживает SSR, то загружайте данные на сервере. Если роутер поддерживает лоадеры, то загружайте в лоадерах.

const issuesQuery = { queryKey: ['issues'], queryFn: fetchIssues }

queryClient.prefetchQuery(issuesQuery)

function Issues() {
const issues = useQuery(issuesQuery)
}


Во-вторых, если у вас данные в списке и нужен отдельный элемент из списка, то его можно получить из кэша:

const data = useQuery({
queryKey: ['todos', 'detail', id],
queryFn: () => fetchTodo(id),
initialData: () => {
return queryClient
.getQueryData(['todos', 'list'])
?.find((todo) => todo.id === id)
},
})


Другой подход – создавать кэш для отдельного элемента после получения данных для списка:

const data = useQuery({
queryKey: ['todos', 'list'],
queryFn: async () => {
const todos = await fetchTodos()
todos.forEach((todo) => {
queryClient.setQueryData(['todos', 'detail', todo.id], todo)
})
return todos
},
})


Минус такого подхода в том, что данные могут устареть до момента, когда они понадобятся, либо эти данные могут вообще не понадобиться.

https://tkdodo.eu/blog/seeding-the-query-cache
👍5👎1
Feature-Sliced Design: эволюция фронтенда для быстрых экспериментов

Небольшой обзор от Евгения Валяева, в котором описывается подход к разработке проекта с использованием FSD.

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

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

https://habr.com/ru/company/inDrive/blog/693768/
👍20🔥7👎3
Бесплатный Community Day HolyJS 2022 Autumn — 11 ноября, онлайн

Community Day — это второй день конференции HolyJS со свободным доступом для всех желающих. Организаторы проводят его, чтобы усилия команды и Программного комитета оценило как можно больше участников.

На Community Day такая же насыщенная программа, как и в другие дни конференции. Там будут:
7️⃣ докладов с дискуссиями
2️⃣ воркшопа: улучшаем доступность маркетплейса для незрячих и пишем игру на React
BoF-сессия про микрофронтенды

Бесплатная регистрация на holyjs.ru
👍2🔥2
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