Заметки про React – Telegram
Заметки про React
3.78K subscribers
34 photos
8 videos
485 links
Короткие заметки про React.js, TypeScript и все что с ним связано
Download Telegram
Гайд по необязательным параметрам в 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
React Canaries

Команда React представила новый канал релизов – Canary. Этот канал позволит фреймворкам типа Next.js адаптировать новые фичи раньше официального стабильного релиза.

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

В блоге команда React описала процесс релиза новых фич. В экспериментальных релизах React в API фичи имеют префикс experimental_ или unstable_. По мере использования фичи, если всех устраивает то как она устроена, то она будет избавлена от префиксов и зарелизена в Canary. На этом этапе также будет добавлена документация по фиче.

https://react.dev/blog/2023/05/03/react-canaries
👍84👎1
Контекст, композиция и гибкость

Автор на примере поля ввода показывает, как улучшить гибкость компонента с помощью контекста. Если в компоненте есть разные варианты отображения, которые устанавливаются от страницы к странице, то можно использовать контекст для управления отображением компонента. Например:

function Input({ id, label, required = false }) {
const variant = useInputStyleContext()

const getHelperText = () => {
if (variant === 'showOptionals' && !required) return ' (optional)'
if (variant === 'showRequireds' && required) return '*'

return null
}

return (
<div>
<label htmlFor={id}>
{label}
{getHelperText()}
</label>
<input id={id} required={required} />
</div>
)
}


https://kyleshevlin.com/context-composition-and-flexibility
👍4
Изучаем React Server Component по викторинам

Дэн Абрамов провел опрос по React Server Component. В результате оказалось, что почти половина ответов неверны. RSC сложный, особенно это связано с тем, что по ней нет нормальной документации.

Херрингтон Даркхолм объяснил, как работает RSC изнутри, и по шагам показал, какие происходят действия при рендере компонента. Если кратко, то серверные компоненты передаются на клиент в виде JSON. Серверные компоненты, которые используют async/await вначале заменяются на клиенте на плейсхолдеры, а после выполнения передаются в браузер.

https://betterprogramming.pub/grok-react-server-component-by-quizzes-df4417905bc4
👍4🔥2
WunderGraph как альтернатива Vercel

Vercel предоставляет удобный сервис для деплоя ваших приложений. Но у него дорогие дополнительные услуги хранения: Vercel Postgres, Vercel KV и Vercel Blob.

В качестве альтернативы можно выбрать WunderGraph. Это open-source проект, который добавляет бэкенд для фронтенда. Можно выбрать свою базу данных или сервис с OpenApi, и WunderGraph CLI сгенерирует хуки для использования сервисов в приложении. Для деплоя на собственных серверах можно использовать Docker.

В качестве альтернативных сервисов Vercel Storage можно использовать Neon Tech для Postgres, Upstash как KV хранилище и Cloudflare R2 для хранения файлов.

https://javanoscript.plainenglish.io/dodging-the-vercel-storage-tax-there-are-better-open-source-alternatives-ef04e537b598
👍15
Понимание React Concurrency

В React 18 появились новые фичи Concurrency: useTransition и useDeferredValue. В своем блоге Слава Князев написал, как концептуально работают эти фичи изнутри.

Основная мысль React Concurrency в том, что при рендере следующего отображения текущее отображение остается отзывчивым. Под капотом для достижения такого эффекта используется requestIdleCallback() для вызова рендеринга приложения:

function renderConcurrent(Component) {
// Рендер отменяется, если стейт устарел
if (isCancelled) return;

for (let Child of Component) {
// Выполнить работу когда браузер освободится
requestIdleCallback(() => renderConcurrent(Child));
}
}


https://www.bbss.dev/posts/react-concurrency/
👍12
Legend-State 1.0

Вышел релиз библиотеки для управления состоянием Legend-State. Эта библиотека заявляет, что является одной из самых быстрых по бенчмаркам и может весить всего 3Кб.

Библиотека основана на Observables. Компонент в React будет обновляться только тогда, когда изменятся данные, которые он использует.

В библиотеке есть встроенный плагин для сохранения стейта в localStorage или IndexedDB для создания персистентности.

Также библиотека предоставляет набор компонентов для реактивности, которые позволяют уменьшить количество рендеров компонента. Поддерживаются следующие реактивные элементы, которые обновляются сами без ре-рендера компонента:
- Текстовые элементы
- Пропсы элемента
- Компоненты управления потоком
- Двусторонний биндинг элементов ввода

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

function Component({ children }) {
// Этот компонент рендерится только один раз
const state = useObservable({ show: false, toggles: 0, text: 'Change me' })

useInterval(() => {
state.show.set(v => !v)
state.numToggles.set(v => v + 1)
}, 1000)

// Пропсы заканчивающиеся на $ биндят проп к Observable
// для конкретных изменений без ре-рендера
return (
<div>
<Legend.input value$={state.text} />
<Legend.div
className$={() => (
state.text.get().includes('Legend') && 'font-bold text-blue-500'
)}
>
{state.text}
</Legend.div>
<div>
Modal toggles: {state.numToggles}
</div>
<Show
if={state.show}
else={<div>Not showing modal</div>}
>
<div>Modal</div>
</Show>
</div>
)
}


https://legendapp.com/open-source/legend-state-v1/
👍11👎5
Как избежать моков в тестах с React Router

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

Для обертки компонента для тестов нужно использовать MemoryRouter. Вот пример такой функции, которая создана поверх render из RTL:

import React, { isValidElement } from "react";
import { render } from "@testing-library/react";
import { RouterProvider, createMemoryRouter } from "react-router-dom";

export function renderWithRouter(children, routes = []) {
const options = isValidElement(children)
? { element: children, path: "/" }
: children;

const router = createMemoryRouter([{ ...options }, ...routes], {
initialEntries: [options.path],
initialIndex: 1,
});

return render(<RouterProvider router={router} />);
}


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

it("should ensure the page is rendered", () => {
renderWithRouter(<About />);

expect(screen.getByText("About page")).toBeInTheDocument();
});


https://webup.org/blog/how-to-avoid-mocking-in-react-router-v6-tests/
👍6
Практикуйте React, исправляя тесты

Если вы сомневаетесь в своих знаниях JSX, то можете их проверить. Есть репозиторий с тестами, которые помогут проверить знания JSX. Каждому тесту дано описание и нужно сделать так, чтобы он выполнялся. Ну а если не хочется клонировать репозиторий, то можно сделать это в браузере в CodeSandbox.

https://reactpractice.dev/exercise/practice-react-by-fixing-tests-check-your-jsx-knowledge/
👍71
Борьба с раздуванием HTML

Разделение интересов, к которому стремятся в UI библиотеках, позволяет больше переиспользовать компоненты, но ведет к раздуванию HTML. Одни компоненты создают отступы, другие стилизуют что-то и т.д. Это приводит к созданию лишних компонентов-оболочек.

Причины, по которым не нужны лишние компоненты-оболочки:

1. Раздутый HTML вредит производительности.
2. Избыточные элементы создают проблемы с доступностью.
3. Избыточные элементы могут нарушить стиль.
4. Раздражает работать с глубоко вложенными DOM деревьями.

В своем блоге Элиза Хайн подготовила набор техник, которые позволяют сделать компоненты гибкими и не раздувать HTML.

https://elisehe.in/2023/03/27/minimal-html-in-design-systems
👍9
Как сделаны типы React

В блоге JSer показали основные типы React, которые используются чаще всего, а также показали их исходный код с комментариями. Например, в статье объясняется в чем отличие ReactElement от ReactNode. Если коротко, то используется аналогия с вебом: Node и Element, где Element является подтипом Node. Также и в React, ReactElement является подтипом ReactNode.

interface ReactElement<
P = any,
T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>
> {
type: T;
props: P;
key: Key | null;
}

type JSXElementConstructor<P> =
| ((
props: P,
) => ReactElement<any, any> | null)
| (new (props: P) => Component<any, any>);


ReactElement может быть как <Component>, так и любой HTML тег, например <p>.

https://jser.dev/2023-05-31-react-types-in-typenoscript/
4👍2
RSC с нуля

Дэн Абрамов написал большой гайд с глубоким погружением в работу RSC о том, как реализовать RSC с нуля.

Этот гайд не объясняет преимуществ RSC или то, как реализовать приложение с помощью RSC. Этот гайд для тех, кто любит новые технологии и готов внедрять их с нуля.

Гайд поделен на части, в каждой из которых показывается, как создать что-то существующее с нуля. Например, как рендерить JSX в HTML, как сделать поддержку асинхронности в компонентах и как обновлять JSX с сервера на клиенте.

https://github.com/reactwg/server-components/discussions/5
🔥10👍1
Несколько уровней абстракций в UI библиотеке

В блоге Spotify рассказали как делают UI библиотеку, чтобы сохранялся баланс между кастомизацией и конфигурацией компонентов. Кастомизация обеспечивает свободу и скорость разработки, а конфигурация обеспечивает связность и удобство сопровождения за счет использования абстракций. Чем больше абстракций, тем больше контроля со стороны разработчика UI библиотеки и меньше вводимых данных со стороны пользователя.

В Spotify у компонента есть несколько уровней абстракций. Можно использовать компонент как есть, так и кастомизировать компонент, передав в него любое содержимое. Есть три варианта использования:

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

https://engineering.atspotify.com/2023/05/multiple-layers-of-abstraction-in-design-systems/
👍13
Почему клиентские компоненты во время SSR преобразуются в HTML?

Когда появился React Server Components, произошло разделение на клиентские и серверные компоненты. Дэн Абрамов сделал небольшое визуальное объяснение различий между Client Tree (уже существующим) и Server Tree, который был добавлен в RSC.

Исходя из поста клиентские компоненты (Client Tree) - это обычные компоненты React, которые мы использовали раньше. Во время SSR клиентские компоненты выполняются на сервере и преобразуются в HTML для инициализации страницы, как и раньше.

https://github.com/reactwg/server-components/discussions/4
👍5