Заметки про React – Telegram
Заметки про React
3.78K subscribers
34 photos
8 videos
485 links
Короткие заметки про React.js, TypeScript и все что с ним связано
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
Красивые эффекты с WebGL Render Targets

Максим Хекель сделал руководство по созданию оптических иллюзий и эффектов переходов с помощью WebGL Render Targets.

https://blog.maximeheckel.com/posts/beautiful-and-mind-bending-effects-with-webgl-render-targets/
7👍1
Что такое Vite и почему вы должны использовать его вместо CRA

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

Vite работает гораздо быстрее. Вместо пересборки всего билда, Vite работает по другому. Зависимости приложения, которые редко меняются, упаковываются в один бандл. А исходный код приложения не упаковывается в бандл, а распространяется через нативный ESM. Для production сборки используется бандлинг через Rollup.

https://luketheweb.dev/blog/what-is-vite-and-why-should-you-use-it-instead-of-create-react-app
👍12👎1
Ленивая загрузка роутов в React Routes

В React Router 6.4 была представлена концепция “Data Router”, основное внимание которого уделяется разделению получения данных и рендеринга для исключения “водопадов” загрузки данных.

В React Router 6.9 появилась возможность ленивой загрузки роутов с компонентом и функцией получения данных. Пример:

// app.jsx
import Layout, { getUser } from `./layout`;
import Home from `./home`;

const routes = [{
path: '/',
loader: () => getUser(),
element: <Layout />,
children: [{
index: true,
element: <Home />,
}, {
path: 'projects',
lazy: () => import("./projects"), // 💤 Lazy load!
children: [{
path: ':projectId',
lazy: () => import("./project"), // 💤 Lazy load!
}],
}],
}]

// projects.jsx
export function loader = () => { ... };
export function Component() { ... }

// project.jsx
export function loader = () => { ... };
export function Component() { ... }


Обратите внимание на наименование экспортируемых переменных: loader и Component.

React Router может загружать lazy роуты параллельно. При переходе по URL /projects/123 будут параллельно загружены роуты и выполнены loader функции, после чего будет отрендерен компонент.

https://remix.run/blog/lazy-loading-routes
👎10👍3
Мультиязык в Next.js с помощью серверных компонентов

Ян Аманн рассказал, как сделать мультиязычный сайт с помощью next-intl и серверных компонентов в Next.js.

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

Стоит учитывать, что в серверных компонентах нельзя использовать хуки, например, useState и useEffect. В этом случае одним из вариантов хранения состояния на странице может стать URL search params.

https://www.smashingmagazine.com/2023/03/internationalization-nextjs-13-react-server-components/
👍41
React Labs: над чем мы работали – март 2023

В постах React Labs команда React пишет об исследовательских проектах и текущих разработках, которые могут попасть в релиз. С момента последнего релиза произошли большие изменения:

- Серверные компоненты. Достигли соглашения по использованию директивы "use client" для обозначения только клиентских компонентов. Сделали async / await как основной способ получения данных в серверных компонентах, и хук use для клиентских компонентов. Сейчас ведется разработка того, как отправлять данные с клиента на сервер – Server Action.

- Asset Loading. Ведется разработка интеграции Suspense и загрузки ресурсов: стилей, шрифтов и изображений. Команда React хочет, чтобы эта фича работала без рефакторинга существующих компонентов. В качестве оптимизации предоставят возможность ручной загрузки ресурсов напрямую из компонента.

- Метаданные документа. Появилась возможность использовать теги <noscript>, <meta> и <link> внутри компонента, и они будут установлены внутри тега <head>. Это решает проблему поточного серверного рендера.

- React Optimizing Compiler. Команда React продолжает делать компилятор React Forget. Основная цель компилятора в том, чтобы компонент ре-рендерился только когда изменится значение пропа. Сейчас React ре-рендерит компонент, когда изменится ссылка на объект. С React Forget компонент будет ре-рендерится при изменении семантического значения.

- Offscreen Rendering. Эта фича позволяет рендерить компоненты в фоновом режиме без дополнительных затрат на производительность. Похожа на CSS свойство content-visiblity. Большинство разработчиков не будет напрямую работать с offscreen API, а будут взаимодействовать через существующие роутеры и UI библиотеки.

Transition Tracing. Это API позволит определять, когда хук useTransition становится медленнее, и выяснить, почему это происходит.

https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023
👍13👎1
Переосмысление лучших практик React

React 18, наряду с React Server Components, сделал значительный шаг в сторону серверного рендера. Особенно это видно в таких фреймворках как Remix и Next, где поток данных распространяется на сервер, и приложение превращается в MPA с интерактивностью SPA.

На FrontendMastery вышла статья, в которой проведен анализ эволюции React от библиотеки представления на стороне клиента до фреймворков с рендером на сервере.

https://frontendmastery.com/posts/rethinking-react-best-practices/
👍12
React Chrono – гибкий компонент таймлайна

Вышел релиз второй версии библиотеки React Chrono. С помощью этой библиотеки можно рендерить кастомизируемые таймлайны в вертикальной и горизонтальной ориентации. В новой версии появилась возможность рендерить вложенные таймлайны.

https://react-chrono.prabhumurthy.com/
👍8
Написание собственной библиотеки Сигнал

Люк Шафер в своем блоге сделал туториал по созданию собственной библиотеки наподобие Сигнал. Получилась упрощенная версия без оптимизаций, но достаточная, чтобы понять саму концепцию.

Сигнал в основном используется в SolidJS и также был добавлен в Angular, Preact и Qwik. Сигнал можно использовать и в React, используя @preact/signals-react.

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

export function Counter() {
const [count, setCount] = createSignal(0);

return <button onClick={() => setCount(count() + 1)}>{count()}</button>
}


https://www.lksh.dev/blog/writing-your-own-reactive-signal-library/
👍7
Увеличиваем скорость работы Tanstack Table быстрее в 1000 раз

В блоге Jp Camara статья с разбором проблемы с производительностью библиотеки ​​Tanstack Table. Проблема была в том, что при использовании таблицы с группировкой столбцов, рендеринг 50к строк занимал 30-40 секунд. Использовать браузерный профайлер было невозможно из-за слишком медленной работы приложения. Поэтому для оценки скорости рендера и поиска проблемных мест использовался console.time.

Проблема была обнаружена внутри функции группировки библиотеки Tanstack Table:

function groupBy(rows, columnId) {
const groupMap = new Map<any, Row<TData>[]>()

return rows.reduce((map, row) => {
const resKey = `${row.getValue(columnId)}`
const previous = map.get(resKey)
if (!previous) {
map.set(resKey, [row])
} else {
map.set(resKey, [...previous, row])
}
return map
}, groupMap)
}


Здесь использовался спред оператор […previous, row] для конкатенации текущей строки в конец массива. Так как он использовался внутри другого цикла reduce, то сложность функции группировки была O(n^2). Поэтому для 50к строк выполнялось 2,5 миллиарда итераций.

https://jpcamara.com/2023/03/07/making-tanstack-table.html
🔥4👍1
Modern.js – фреймворк от ByteDance

Modern.js - это фреймворк на React от ByteDance. Возможно, вы не слышали о нем, но это полноценный фреймворк на React, у которого уже вышла 2ая версия, и есть готовая экосистема инструментов.

Фреймворк похож на Next.js и Remix. Роутинг на основе структуры в файловой системе, и есть файлы layout и page для рендера страниц. Для загрузки данных используются файлы layout.loader.ts и page.loader.ts, в которых экспортируются функции получения данных. Для получения данных в компоненте страницы используется хук useLoaderData.

// page.loader.ts
export type ProfileData = {
/* some types */
};

export default async (): Promise<ProfileData> => {
const res = await fetch('https://api/user/profile');
return await res.json();
};

// page.tsx
import { useLoaderData } from '@modern-js/runtime/router';
import type { ProfileData } from './page.loader.ts';

export default function UserPage() {
const profileData = useLoaderData() as ProfileData;
return <div>{profileData}</div>;
}


Другие возможности:
- Создание BFF. Для этого нужно добавить BFF плагин в конфиг, и можно определять свои функции в папке /api.
- Кастомизация веб-сервера. Можно добавить обработку аутентификации пользователя, пререндеринг скелетона приложения и т.д.
- Встроенная поддержка микро-фронтенда. Через конфиг можно настроить работу нескольких фронтенд приложений.
- Есть встроенный стейт-менеджер – Reduck, созданный на основе Redux.

Помимо фреймворка в экосистеме есть Modern.js Module и Modern.js Doc. Это инструменты для создания npm пакетов и фреймворк для создания документов соответственно.

https://modernjs.dev/en
👍4
Популярные ошибки при работе с React

В блоге Alex Khomenko вышел обзор популярных ошибок при работе с React. Некоторые из них:

Изменение стейта напрямую

При обновлении не примитивных значений, таких как объект или массив, нужно предоставить другую ссылку на объект. В ином случае, React не поймет, что стейт изменился и нужно сделать ре-рендер. Для решения проблемы можно использовать спред оператор, map для изменения объектов внутри массива, новое API structuredClone или библиотеки для работы с иммутабельностью, например Immer.js.

Забыть, что обновление стейта происходит асинхронно

Часто бывает, что пытаются обратиться к значению стейта сразу после его установки:

function Counter() {
const [count, setCount] = useState(0);

const increment = () => {
setCount(count + 1);
console.log(count); // 0
};
}


Однако, значение стейта обновится только при следующем рендере. Следовательно, нет смысла сразу читать значение стейта после установки. Для решения проблемы можно использовать useEffect.

https://claritydev.net/blog/the-most-common-mistakes-when-using-react
👍6👎41
Сборник задач по TypeScript

Type Challenges – большой сборник задач по TypeScript, разбитый по категориям и уровню сложности. Решать задачи предлагается в песочнице TypeScript, там же уже есть тесты для проверки решения. Этот проект своего рода LeetCode, только для тренировки навыков написания TypeScript типов.

https://github.com/type-challenges/type-challenges

Еще один интересный проект по TypeScript – курс по типам от автора библиотеки TS-Pattern. Хоть курс и платный, первые четыре статьи бесплатные. В них много интересного материала по созданию типов в TypeScript, и в конце статьи есть задачи на практику.

https://type-level-typenoscript.com/
🔥153
Скажем нет “мерцающему” UI: useLayoutEffect и браузерная отрисовка

Надя Макаревич разобрала в своем блоге как работает хук useLayoutEffect и в чем его разница с useEffect, как работает браузерная отрисовка и как подружить useLayoutEffect и SSR.

Основное отличие в том, что useLayoutEffect запускается синхронно перед отрисовкой браузера. А useEffect будет запускаться асинхронно после отрисовки браузера, но это не гарантировано.

При SSR возможны “мерцания” интерфейса, если например где-то рендерятся компоненты по условию, вычисляемому в useLayoutEffect. Причина в том, что между моментом отрисовки браузером HTML/CSS полученного от сервера до выполнения useLayoutEffect проходит некоторое время. На сервере useLayoutEffect не выполняется, поэтому пользователю придется ждать когда он выполнится на клиенте после загрузки и исполнения JS. Чтобы избежать “мерцания” можно на сервере возвращать заглушку компонента.

https://www.developerway.com/posts/no-more-flickering-ui
2👎1
Гайд по необязательным параметрам в React

React API содержит несколько необязательных и альтернативных параметров. Большинство из них предназначены для оптимизации, поэтому будет полезно о них знать.

В блоге Джулс Блом вышел анимированный гайд по необязательным и альтернативным параметрам в React, которые редко используются. Например, useState принимает альтернативный аргумент – функцию инициализации. Этот подход можно использовать для ленивых вычислений, если нужно передать в стейт тяжелое вычисление или прочитать из localStorage. В таком случае, операция будет произведена один раз – при первом рендере компонента:

const getInitialState = () => Number(window.localStorage.getItem('count'))
const [count, setCount] = React.useState(getInitialState)


https://julesblom.com/writing/react-optional-parameters
👍7
Релиз TypeScript 5.1 Beta

Вышел релиз TypeScript 5.1 Beta, в котором есть несколько изменений для React.

Главное из них в том, что TypeScript позволит библиотекам объявлять свой собственный валидный JSX тип элемента. Связано это с тем, что в текущий момент функция компонента может вернуть только null | JSX.Element. Однако, в React компоненты могут возвращать ReactNode. Этот тип включает в себя number | string | Iterable<ReactNode> | undefined и также в будущем будет включать Promise<ReactNode>.

Таким образом, при обновлении на TypeScript 5.1+ открываются следующие возможности:
- использование асинхронных серверных компонентов.
- в функциях компонента возвращать значение из списка ReactNode без использования Fragment.
- другие возможности, такие как зеркальный курсор для редактирования JSX тега в VSCode и использование атрибутов JSX с пространством имен.

https://devblogs.microsoft.com/typenoscript/announcing-typenoscript-5-1-beta/
8
Новый хук useFormStatus

В React смержен ПР с добавлением нового экспериментального хука useFormStatus. Этот хук читает статус формы родительского компонента, если он существует:

const {pending, data, action, method} = useFormStatus();


Его можно использовать для отображения индикатора загрузки. Хук сделан на основе хука useTransition. Для реализации внутри используется startTransition и объект контекста.

https://github.com/facebook/react/pull/26722
👍9👎4🔥2
Анимация View Transitions в React

View Transitions API предлагает простой способ перехода визуального изменения DOM из одного состояния в другое.

На patterns.dev вышел обзор от Дом Кристи, в котором он объясняет, как использовать View Transition API в React и вместе с Next.js App Router.

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

https://www.patterns.dev/posts/view-transitions
👍5🔥1
Как структурировать Next.js приложения

В Next.js роутинг приложения и шаблоны основаны на расположении файлов. Этот подход влияет на то, как создаются приложения на Next.js.

Алекс Кондов в своем блоге описал, как структурировать Next.js приложения. За основу был взят принцип совместного размещения (co-location). В идеале вещи, которые связаны, должны находиться рядом. Поэтому можно создать папку модули, в которой будут находиться модули по доменам. Однако, по умолчанию в Next.js часть логики домена будет храниться в странице – в getServerSideProps и компоненте. Это приводит к фрагментации логики приложения.

Чтобы решить эту проблему, можно использовать гексагональную архитектуру и использовать роутинг Next.js как адаптер к нашей логики. Компонент страницы и логику getServerSideProps можно хранить в модулях и импортировать в страницу роута Next.js:


import ItemsPage from "modules/items/ItemsPage";
import itemsPageProvider from "modules/items/itemsPageProvider";

export default function Page({ user }) {
return <ItemsPage user={user} />
}

export async function getServerSideProps(context: NextPageContext) {
const { req, query } = context
const props = itemsPageProvider.getPageProps(req, query)
return { props }
}


https://alexkondov.com/structuring-next-applications/
👍3👎2
This media is not supported in your browser
VIEW IN TELEGRAM
Создание анимированного тултипа с помощью Framer Motion

Гайд по созданию компонента тултипа с помощью библиотек Framer Motion и Floating UI. В нем подробно описывается каждый шаг использования конкретного хука и функции. Помимо обычного тултипа, в гайде описано как создать групповой тултип с анимацией перехода.

https://sinja.io/blog/animated-tooltip-with-react-framer-motion
👍5
Что такое React Server Components

React Server Components стирает грань между сервером и клиентом, позволяя React компонентам загружать данные на сервере и отправлять отрендеренный компонент клиенту.

Преимущество React Server Components в уменьшении нагрузки браузера и уменьшении JS бандла клиента. Также уменьшается сетевой водопад браузера.

Выглядят React Server Components так же, как и обычные, только в них есть ряд ограничений. Например, в них нельзя использовать хуки.

Также вышел релиз Next.js 13.4, в котором они объявили стабильным новый роутер с React Server Components. Это значит, что RSC можно использовать в продакшене.

https://www.viget.com/articles/what-even-are-react-server-components/
👍9👎1
Курс по React и TypeScript

Бесплатный курс от Matt Pocock по использованию TypeScript в React. Автор объясняет с самых азов, поэтому курс подойдет для начинающих.

В курсе автор объясняет как читать типы React для дебага ошибок и правильного использования, какие использовать React типы для компонентов и хуков и т.д.

https://www.totaltypenoscript.com/tutorials/react-with-typenoscript
👍6