Заметки про React – Telegram
Заметки про React
3.78K subscribers
34 photos
8 videos
485 links
Короткие заметки про React.js, TypeScript и все что с ним связано
Download Telegram
Новая документация React готова на 99%

По сообщению Дэна Абрамова для того, чтобы вывести новую документацию из беты, осталось сделать сайт лендинга.

Новая документация по React уже готова и она отличается от текущей:
- Все примеры приведены с использованием хуков, а не классовых компонентов.
- Гораздо больше интерактивных примеров и визуальных диаграмм.
- В гайдах есть задачи для проверки понимания.

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

https://beta.reactjs.org/
🔥33👍91👎1
Релиз TypeScript 5.0 Beta

На днях вышел релиз мажорной версии TypeScript 5.0 Beta. В этом релизе много новых фич. Кратко о некоторых фичах релиза:

Новый стандарт декораторов

В TS уже были декораторы, и они были доступны под флагом. В версии 5.0 декораторы будут доступны без флага, а те декораторы, которые были доступны под флагом, объявлены как легаси. Пример использования новых декораторов:

function loggedMethod<This, Args extends any[], Return>(
target: (this: This, ...args: Args) => Return,
context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>
) {
const methodName = String(context.name);

function replacementMethod(this: This, ...args: Args): Return {
console.log(`LOG: Entering method '${methodName}'.`)
const result = target.call(this, ...args);
console.log(`LOG: Exiting method '${methodName}'.`)
return result;
}

return replacementMethod;
}

class Person {
// --snip--

@bound
@loggedMethod
greet() {
console.log(`Hello, my name is ${this.name}.`);
}
}


Для работы с декораторами добавлен новый тип ClassMethodDecoratorContext, который моделирует объект контекста, который принимают декораторы метода.
У метода может быть несколько декораторов. В примере сначала выполнится @loggedMethod, а потом @bound.
Декораторы можно использовать не только у метода, но и у класса и его полей.

const как параметр типа

В TS есть утверждение as const, которое делает выражение иммутабельным и говорит компилятору, что тип больше не будет расширяться.
В TS 5.0 можно добавить const как модификатор к объявлению типа параметра. Пример:

type HasNames = { names: readonly string[] };
function getNamesExactly<const T extends HasNames>(arg: T): T["names"] {
return arg.names;
}

// readonly ["Alice", "Bob", "Eve"]
const names = getNamesExactly({ names: ["Alice", "Bob", "Eve"] });


При этом использование модификатора const не требует ограничения типа в виде readonly. Если не использовать readonly, то результат будет другим:

declare function fnBad<const T extends string[]>(args: T): void;

// 'T' будет 'string[]', а не 'readonly ["a", "b", "c"]'
fnBad(["a", "b" ,"c"]);


Несколько конфиг файлов в extends

Появилась возможность расширять tsconfig от несколько файлов:

{
"compilerOptions": {
"extends": ["a.json", "b.json", "c.json"]
}
}


В этом случае b.json расширяет a.json, а c.json расширяет b.json, а текущий конфиг расширяет c.json.

https://devblogs.microsoft.com/typenoscript/announcing-typenoscript-5-0-beta/
👍13
PR с заменой CRA на Vite

В репозитории reactjs.org стал популярным PR с предложением использовать Vite вместо CRA.

На это предложение ответил Дэн Абрамов. В своем комментарии он рассказал историю CRA и ее цели. Основной посыл заключается в том, что команда React не хочет забрасывать CRA, но и не хочет его рекомендовать. Важно создавать новые приложения с поддержкой SSG/SSR. В CRA же нет поддержки SSG/SSR.

Одной из целей развития CRA видят превращение его в CLI лаунчер: давать на выбор фреймворк для создания приложения: Next.js, Remix, CRA и т.д. Также возможно в будущем react-noscripts для сборки приложения перейдет на Vite.

https://github.com/reactjs/reactjs.org/pull/5487#issuecomment-1409720741
👍12
React рекурсивно ре-рендерит дочерние компоненты, но есть нюанс

Алекс Сидоренко в своем блоге сделал наглядную визуализацию того, как разделение компонентов и использование совместного размещения состояния (state colocation) позволяют предотвращать лишний рендер.

https://alexsidorenko.com/blog/react-render-children-prop/
👍9🔥21
React.js: Документальный фильм

Вышел документальный фильм про React. В нем рассказывается история создания библиотеки от самих разработчиков. В фильме снялись Том Оккино, Кристофер Чедо, Пит Хант, Себастьян Маркбоге, Дэн Абрамов и многие другие.

https://www.youtube.com/watch?v=8pDqJVdNa44
🔥8👍4
Гайд по обработке ошибок в React

В блоге Нади Макаревич вышел гайд по обработке ошибок в React.

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

Для того, чтобы предотвратить такие ситуации и отловить ошибку во время фазы жизненного цикла React, есть Error Boundaries. У него есть минусы: если возникла ошибка в колбеке или в асинхронном коде, то такая ошибка не дойдет до Error Boundaries:

const Component = () => {
useEffect(() => {
// Будет обработан ErrorBoundary
throw new Error('Destroy everything!');
}, [])

const onClick = () => {
// Не будет обработан ErrorBoundary
throw new Error('Hulk smash!');
}

useEffect(() => {
// Если возникнет ошибка, то не будет обработан ErrorBoundary
fetch('/bla')
}, [])

return <button onClick={onClick}>click me</button>
}

const ComponentWithBoundary = () => {
return (
<ErrorBoundary>
<Component />
</ErrorBoundary>
)
}


Чтобы направить ошибку из колбека или асинхронного кода в ErrorBoundary, можно перекинуть ошибку в React используя трюк:

const onClick = () => {
try {
//–snip–
} catch (e) {
// вызвать обновление стейта с выбросом ошибки
setState(() => throw e);
}
}


Чтобы самостоятельно не изобретать колесо, рекомендуется использовать библиотеку react-error-boundary. В ней уже решены основные проблемы, возникающие при обработке ошибок.

https://www.developerway.com/posts/how-to-handle-errors-in-react
🔥7👍5
Переезд с Webpack на Vite для микрофронтенда

История переезда проекта со сборщика Webpack на Vite. Особенность проекта в том, что это микрофронтенд и используется SingleSPA и SystemJS importmap. В свою очередь Vite использует нативные ES6 модули в dev режиме для быстрой разработки. Поэтому использование SystemJS будет только замедлять сборку. Чтобы решить проблему, нужно перейти на нативный importmap и отказаться от SystemJS.

https://habr.com/ru/company/dododev/blog/715988/
👍41🔥1
Что мне нравится в Astro

Дэйв Рэмси сравнивает Astro с Next.js и Gatsby. Автор заметил, что Next.js не очень подходит для сайта-блога. При посещении сайта пользователю приходится загружать слишком много JS, чтобы просто прочитать статью. При переводе сайта с Next.js на Astro автор заметил некоторые вещи, которые нравятся больше, чем в Next.js и Gatsby.

- Поддерживает любой источник данных

Astro никак не ограничивает способ получения данных. Он поддерживает ключевое слово await в шаблоне, поэтому можно записать fetch в переменную и использовать ее в шаблоне:

---
const response = await fetch('https://an-endpoint.com/api');
const data = await response.json();
---
<p>{data.a_property}</p>


- Есть готовые интеграции

В Astro есть гайды по генерации sitemap, RSS ленты и оптимизации изображений. Также есть готовые модули для работы с СЕО.

- Сложно написать непроизводительное приложение

По умолчанию в Astro не создается JS для клиента. Создавать Astro компоненты легко, особенно после опыта написания React компонентов.

- Большая часть API построена на веб-стандартах

Большая часть низкоуровневого API Astro основана на веб-стандартах, поэтому его проще изучить. Например, Astro.request является объектом Request из Fetch API.

https://www.macarthur.me/posts/what-i-like-about-astro
👍4🔥1
Гайд по сужению типов в TypeScript

В своем блоге Владимир Клепов написал подробный гайд по сужению типов в TypeScript. Сужение типов полезно, когда получаешь данные извне: читаешь localStorage, парсишь URL или читаешь пользовательский ввод. Также сужение типа применяется, когда мы расширяем API для удобства, например, вызов функции mount('#mount’) и mount(document.querySelector('#mount’)).

В статье рассматриваются несколько методов безопасного сужения типов:
- Использование нативных JS операторов, таких как typeof, === и других.
- Использование type guard функций. Они полезны, но, как ни странно, небезопасны для типов.
- Написать функцию приведения типа, например (x: unknown) => number.

https://blog.thoughtspile.tech/2023/01/31/typenoscript-safe-narrow/
👍6🔥31
Краткое введение в Tauri

Фернандо Дольо рассказывает о создании простого нативного приложения с использованием Tauri и React. В гайде также есть пример взаимодействия React приложения с Tauri через Rust.

Tauri – это набор инструментов для создания нативных приложений с использованием JS, альтернатива Electron. Написан на Rust, поэтому для взаимодействия с ОС нужно писать код на Rust. В отличие от Electron не использует Chromium для рендера приложения, а использует нативный WebView операционной системы. Плюс такого подхода в том, что размер приложения минимальный. На сайте написано, что размер приложения может быть меньше 600KB. Минус в том, что у каждой ОС свой WebView, поэтому будет отличаться дизайн нативных UI элементов.

https://blog.bitsrc.io/how-to-build-desktop-apps-using-react-a-quick-introduction-to-tauri-63fcad43914e
👍5🔥1
useSignal() — это будущее веб-фреймворков

Signal — это способ хранения состояния приложения, аналогичный useState() в React.

Ключевое различие между Signal и React стейтом в том, что Signal возвращает геттер и сеттер, а React стейт возвращает значение и сеттер.

Miško Hevery сделал сравнение Signal и хуков в React. Signal является реактивным, т.е. он должен отслеживать, кто заинтересован в состоянии, и уведомлять подписчиков об изменении состояния. Это достигается с помощью наблюдения за контекстом, в котором вызывается геттер, создающий подписку.

useState() возвращает значение состояния, а не геттер. React не важно как используется стейт, он будет ре-рендерить сразу все при изменении состояния.

https://www.builder.io/blog/usesignal-is-the-future-of-web-frameworks
👍14👎1
Как избежать хитрых ловушек в асинхронных стейт менеджерах

Иван Буряк и Трэвис Тернер из Злых Марсиан поделились опытом, как избежать хитрых ловушек при работе асинхронными стейт менеджерами в React. Примеры таких стейт менеджеров: Logux, Replicache, RxDB и WatermelonDB. Они позволяют создавать Offline-first сайты, сохраняя данные стейта в локальное хранилище браузера, например, в IndexedDB.

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

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

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

https://evilmartians.com/chronicles/how-to-avoid-tricky-async-state-manager-pitfalls-react
👍8
Релиз Next.js 13.2

Состоялся релиз минорной версии Next.js 13.2. В новой версии основные изменения касаются работы приложения внутри папки app. Часть изменений:

- Встроенная поддержка SEO через Мета-теги

Экспорт переменной metadata или функции generateMetadata() позволяет установить Мета-теги для страницы. Можно использовать как в компонентах страниц, так и в layout:

// app/layout.tsx

import type { Metadata } from 'next';

export const metadata: Metadata = {
noscript: 'Home',
denoscription: 'Welcome to Next.js',
};


- Кастомный обработчик API роутов

Одними из недостающих фич папки app были API роуты из папки pages/api. В версии 13.2 добавлена фича API роутов в папку app, которая позволяет принимать и обрабатывать запросы, используя fetch Request и Response. Обработчики объявляются в файле route.ts и экспортируются под именем HTTP метода.

// app/items/route.ts

export async function GET() {
const cookieStore = cookies();
const token = cookieStore.get('token');

return new Response('Hello, Next.js!', {
status: 200,
headers: { 'Set-Cookie': token=${token} },
});
}


- Поддержка MDX в серверных компонентах

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

- Статическая типизация ссылок

Адрес href у ссылок Link будет проверяться TypeScript на правильность ввода. Эта фича включается в конфиге и будет работать только в папке app.

https://nextjs.org/blog/next-13-2
👍12👎2
Понимание серверных компонентов в React 18 и Next.js 13

Серверные компоненты – это новая концепция, представленная в React 18 и была реализована в Next.js 13 в папке /app. Серверные компоненты позволяют рендерить компоненты на сервере и уменьшить объем JS отправляемого клиенту.

Все компоненты Next.js в папке /app по умолчанию являются серверными компонентами. Чтобы сделать компонент клиентским, нужно добавить директиву ’use client’; в начало файла.

Используйте серверные компоненты, если:
- Нужно сделать запрос из API.
- Используется чувствительная информация: токены, ключи API и т.д.
- Нужен прямой доступ к серверу.
- У компонента есть много зависимостей, что ведет к сильному увеличению клиентского бандла.

https://programmingwithmosh.com/react/understanding-server-components-in-react-18-and-next-js-13/
👍10
Evolu – хуки для local-first разработки

Библиотека для создания local-first приложений. Поддерживает синхронизацию со сквозным шифрованием с использованием CRDT. Для локального хранения данных использует SQLite WASM. Особенности:

- Типизированная схема данных.
- Реактивные запросы.
- Работа в режиме реального времени: синхронизация при восстановление сети.
- Вместо SQL запросов используется типобезопасный query builder.

Описание схемы и создание хуков:

import * as S from "@effect/schema";
import * as E from "evolu";

const TodoId = E.id("Todo");
type TodoId = S.Infer<typeof TodoId>;

const TodoTable = S.struct({
id: TodoId,
noscript: E.NonEmptyString1000,
isCompleted: E.SqliteBoolean,
});
type TodoTable = S.Infer<typeof TodoTable>;

const Database = S.struct({
todo: TodoTable,
});

const { useQuery, useMutation, useOwner, useOwnerActions, useEvoluError } =
E.createHooks(Database);


Выполнение запросов:

const { rows } = useQuery((db) =>
db
.selectFrom("todo")
.select(["id", "noscript"])
.orderBy("updatedAt"),
// (row) => row
({ noscript, ...rest }) => noscript && { noscript, ...rest }
);


https://github.com/evoluhq/evolu
👍3
Читаем исходный код – Chakra UI

Chakra UI – популярная UI библиотека для React. Она модульная и поддерживает кастомизацию компонентов.

Алекс Кондов изучил исходный код библиотеки и поделился интересными абстракциями, которые он нашел. Будет полезно изучить код тем, кто занимается разработкой UI библиотеки.

Пример создания контекста:

export const [ButtonGroupProvider, useButtonGroup] =
createContext<ButtonGroupContext>({
strict: false,
name: 'ButtonGroupContext',
})

export function createContext<T>(options: CreateContextOptions<T> = {}) {
// ...
const Context = createReactContext<T | undefined>(undefined)
// ...

function useContext() {
const context = useReactContext(Context)

if (!context && strict) {
const error = new Error(
errorMessage ?? getErrorMessage(hookName, providerName),
)
// ...
throw error
}

return context
}

return [Context.Provider, useContext, Context] as CreateContextReturn<T>
}


https://alexkondov.com/reading-code-chakra-ui/
👍9🔥2👎1
Почему вы должны использовать React фреймворк

При создании проекта на React, используйте фреймворк, например, Next.js, Gatsby или Remix. Ли Робинсон объяснил, почему это нужно делать:
- Меньше времени на подключение инструментов, больше времени на создание продукта.
- Более легкая адаптация и обучение новых разработчиков.
- Гибкость для различных стратегий рендеринга (браузерная или серверная).
- Меньше “велосипедов” в проекте.
- Есть готовые инструменты для деплоя проекта.

https://leerob.io/blog/react-frameworks
👎9👍5
Эффективный HOC

HOC – концепция пришедшая из функционального программирования. Это функция, которая принимает компонент и возвращает его с дополнительной логикой.

Хотя эта концепция предоставляет безграничное множество вариантов использования, для практичности нужно ограничиться только добавлением дополнительной логики или компонента обертки. В HOC нужно избегать неожиданного поведения: никаких изменений компонента и его пропсов.

Слава Князев в своем блоге написал туториал по HOC. В нем он описал, что можно и нельзя делать с помощью HOC.

Пример HOC логирования:

const withPropsLogger = (Component) => (
(props) => {
console.log(props);
return <Component {...props}/>
};
);


https://www.bbss.dev/posts/effective-hocs/
👍3🔥1
dnd-kit – drag&drop библиотека для React

Легковесная, модульная и расширяемая библиотека для перетаскиваний в React. Основные фичи:

- Возможность кастомизации алгоритма обнаружения коллизий, рендер оверлея во время переноса и многое другое.
- Поддержка нескольких методов ввода: клавиатура, мышь, touch, pointer.
- Для работы с React предоставляет два хука: useDraggable и useDroppable.
- 0 внешних зависимостей и модульная: ядро библиотеки весит 10Кб.
- Возможность кастомизации анимаций, переходов, стилей и т.д.
- Пресеты: есть готовый пресет @dnd-kit/sortable для создания сортируемых блоков.

Библиотека не использует HTML5 Drag and drop API из-за ограничений в API. В этом API не поддерживаются сенсорные устройства и нет возможности детальной кастомизации поведения. Главный недостаток отказа от HTML5 Drag and drop API в том, что вы не сможете перетаскивать файлы с рабочего стола компьютера или между окнами.

https://docs.dndkit.com/
👍7🔥6
Forwarded from Сова пишет…
Там новая документация реакта наконец-то релизнулась.
Вместе с новым адресом. Старый теперь тоже перенаправляет сюда

https://react.dev/
🔥202
Релиз TypeScript 5.0

Вышла стабильная версия TypeScript 5.0. Авторы обещают, что у большинства разработчиков обновление пройдет гладко.

После RC есть небольшие изменения, основное из них – минимальная поддерживаемая версия Node.js 12.20.

Кроме изменений, описанных в RC, есть другие изменения:

Улучшение enum

Теперь все enum будут enum перечислениями: каждый элемент enum будет иметь уникальный тип. Если в TypeScript 4.9.5 такой код работает:

enum E {
Foo = 10,
Bar = 20,
}

function takeValue(e: E) {}

takeValue(E.Foo);
takeValue(123);


То в TypeScript 5.0 вызов функции takeValue(123) будет выбрасывать ошибку, т.к. 123 не равен ни одному типу E.

Поддержка export type *

// models/vehicles.ts
export class Spaceship {
// ...
}

// models/index.ts
export type * as vehicles from "./vehicles";

// main.ts
import { vehicles } from "./models";


Улучшение поддержки JSDoc

Добавлена поддержка @satisfies и @overload в документации JSDoc.

https://devblogs.microsoft.com/typenoscript/announcing-typenoscript-5-0/
👍4🔥3