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

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

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

Один из способов решения подобных проблем – использование эффектов, о котором подробно рассказал Бен Илегбод в своей статье.

https://www.benmvp.com/blog/handling-react-server-mismatch-error/
👍5
Проблемы в типизации children

Рассмотрим пример компонента:

const Card: React.FC = props => { ... }

export default function App() {
const randomObject = {};
return (
<div className="App">
<Card>{randomObject}</Card>
</div>
);
}

Со стороны TypeScript в данном коде нет ошибок, компонент скомпилируется. Но при запуске приложения будет ошибка со стороны React: Objects are not valid as a React child (found: object with keys {}).
Проблема в том, что неверно написаны типы для React.ReactNode. Если посмотреть в исходники типов, то можно увидеть, что ReactNode расширяется от ReactFragment, который разрешает использование объекта {}.

interface ReactNodeArray extends Array<ReactNode> {}
type ReactFragment = {} | ReactNodeArray;
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;

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

https://fettblog.eu/react-types-for-children-are-broken/
👍8
Лучшие практики React Testing Library

Бен Илегбоду делится лучшими практиками при работе с библиотекой для тестирования Testing Library. Кратко о них:

- Используйте user-event вместо fireEvent для взаимодействия с элементами в компоненте. Библиотека Testing Library экспортирует fireEvent, но её API более низкоуровневое. Гораздо проще и читабельнее будет использование user-event.

- Избегайте прямых запросов в DOM. Вместо querySelector используйте запросы получения элементов в зависимости от их роли, содержимого текста, лейбла и т.д.

- Используйте screen вместо деструктуризации render. Эта практика избавит от постоянного изменения объекта деструктуризации по мере добавления или удаления нужных нам запросов.

- Правильно используйте waitFor. Не кладите в колбек waitFor вызовы функций сайд-эффектов, например, клик по кнопке или ввод текста. Внутри waitFor должно быть только утверждение (expect). Связано это с тем, что waitFor вызывает функцию колбека несколько раз, пока утверждение внутри него не станет верным или закончится время на проверку.

Большинство случаев поддержки лучших практик можно добиться установкой правил ESLint для Testing Library, например, eslint-plugin-testing-library.

https://www.benmvp.com/blog/react-testing-library-best-practices/
👍7
Новая документация React

React запустил бету версию сайта документации beta.reactjs.org. Пока что она в процессе наполнения и не все разделы сайта готовы. Но уже сейчас видно, чем новая документация будет отличаться от старой: будет больше интерактивных примеров, добавятся задачи на понимание принципов работы React. Также во всех примерах и объяснениях будут использоваться хуки, а не классы.

https://beta.reactjs.org/
👍16👎1
Тестирование React компонентов с помощью Testing Library

Вводный гайд как тестировать компоненты с помощью библиотеки Testing Library. Автор покрывает основные сценарии тестирования, включая моки fetch запросов, получение элементов по роли и снапшотное тестирование.
Хорошая статья для тех, кто еще не знаком с Testing Library и хочет научиться писать на нем тесты.

https://dev.to/ohdylan/react-component-testing-54ie
👍5
Кастомные хуки и производительность приложения

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

Например, если есть компонент, выполняющий “тяжелые” вычисления и в него нужно добавить кастомный хук, то лучше этот хук добавить в дочернем компоненте. С таким подходом, при работе с хуком будут происходить ререндеры в дочернем компоненте, не влияя на “тяжелый” родительский компонент.

https://www.developerway.com/posts/why-custom-react-hooks-could-destroy-your-app-performance
👍6
Лучшие практики React

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

- Поддержка кода. В начальной стадии проекта нет проблем с поддержкой. Но с ростом количества требований проект становится все больше. Компоненты становятся сложнее и менее поддерживаемыми.

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

- Уверенное понимание React. Проблема в том, что разработчики плохо понимают как работает React под капотом. Это может привести к багам и проблемам с производительностью приложения.


В статье даны как архитектурные, так и практические советы по написанию кода для начинающих разработчиков. Разберем кратко часть из них:

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

- Поддерживайте порядок импортов. Разделяйте импорты по уровням, например, сначала внешние модули, потом внутренние модули. Управлять порядком импортов можно с помощью линтера.

- Изучайте разные паттерны компонентов. Например, использование compound components позволяет избавиться от проп дриллинга.

- Используйте TypeScript. Статическая типизация в крупных проектах будет большим плюсом.

- Используйте lazy loading / code splitting. Уменьшение размера бандла положительно скажется на скорости загрузки сайта.

- Обрабатывайте ошибки. Используйте обертку React Error Boundary, чтобы перехватывать ошибки в компонентах и, например, передавать эти ошибки на сервер в логи.

https://www.freecodecamp.org/news/best-practices-for-react/
👍12
Какую проблему решают веб-фреймворки

Ноам Розенталь написал исследовательскую серию статей по веб-фреймворкам. В чем популярные фреймворки похожи, а в чем отличаются? Можно ли их заменить на VanillaJS, используя текущие возможности веба, и насколько это будет оправданно.

В качестве основного фреймворка для исследования был выбран React. В дополнение к нему были выбраны три новых фреймворка: SolidJS, Svelte и Lit.

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

На VanillaJS, для реализации в своем приложении паттернов из популярных фреймворков можно использовать уже готовые вещи из веб-платформы. Для декларативного стиля программирования использовать HTML и CSS, а для реактивности использовать CSS каскад.

Часть 1. https://www.smashingmagazine.com/2022/01/web-frameworks-guide-part1/
Часть 2. https://www.smashingmagazine.com/2022/02/web-frameworks-guide-part2/
👍5
Производительные React приложения с помощью Context

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

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

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

https://www.developerway.com/posts/how-to-write-performant-react-apps-with-context
👍7
Использование глобальной мемоизации в React

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

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

https://thoughtspile.github.io/2022/02/09/react-global-memo/
👍7
Повышаем производительность приложения используя ​​React Profiler

React Profiler появился в 2018, но до сих пор пользуется не слишком большой популярностью. На inDepthDev делается разбор этого инструмента. На примере небольшого приложения происходит поэтапное улучшение его производительности, используя React Profiler.

React Profiler позволяет проанализировать, как много коммитов было сделано и какие компоненты были отрендерены, и сколько времени на это ушло. React Profiler не работает “на лету”, сначала нужно сделать запись сеанса профилирования, а уже потом проводить анализ.

Если понимать как работает React Profiler, то можно добиться серьезного увеличения производительности вашего React приложения.

https://indepth.dev/posts/1497/react-profiler
👍6🔥1
Популярный стек для React

Экосистема React большая, постоянно появляются новые библиотеки и инструменты. Йоханнес Кеттманн собрал наиболее популярный стек для React. В качестве способа подсчета популярности является количество скачиваний библиотеки в npm.

Самые популярные библиотеки React:
- Next.js – фреймворк с серверным рендерингом из коробки.
- Redux – библиотека для управления стейта.
- react-query или Apollo – для получения данных.
- react-hook-form или Formik – управление формами.


Популярные библиотеки для написания тестов:
- Jest – для запуска тестов.
- React Testing Library – написание интеграционных тестов.
- Cypress – написание E2E тестов.
- Storybook – для документации и тестирования компонентов.

#beginner

https://profy.dev/article/react-tech-stack
👍6
CSS анимации используя React

CSS анимации предоставляют декларативное API для анимации DOM элементов. Нужно всего лишь указать параметры анимации и определить keyframes, описывающие поведение в заданных точках. Тем не менее, в приложениях, где используется много анимаций, будет сложно поддерживать большое количество анимаций, написанных в CSS.

В техническом блоге BBC рассказали про декларативный подход к использованию CSS анимаций в React через компоненты-анимации. Такой подход позволяет через композицию объединить несколько анимаций.

<FadeIn duration={2} delay={0}>
<Zoom from={1} to={2} duration={2} delay={2}>
<FadeOut duration={2} delay={4}>
<RedBox />
</FadeOut>
</Zoom>
</FadeIn>

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

https://medium.com/bbc-design-engineering/css-animations-as-a-dom-based-animations-framework-d6ef582c033a
👍5
Создаем свой React с рендером и useState за 30 минут

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

В React используется синтаксис JSX. Для компиляции JSX в JavaScript можно выбрать TypeScript или babel. При компиляции выражение <h1>React, what are you?</h1> превратится в React.createElement("h1", null, "React, what are you?").

Функция createElement принимает три параметра: тег, атрибуты и содержимое. В качестве содержимого могут быть другие вложенные элементы. Функция createElement возвращает объект React элемента, рендер которого происходит в ReactDOM.render. ReactDOM.render рекурсивно рендерит всех наследников переданного элемента и добавляет атрибуты к DOM элементу.

https://habr.com/ru/post/652487/
👍7
Griffel – новый CSS-in-JS от Microsoft

Microsoft презентовал свою CSS-in-JS библиотеку для стилизации React приложений. Основные фичи:
- возможность компиляции CSS во время сборки и в runtime
- типизация стилей через csstype
- использование Atomic CSS для переиспользования стилей и предотвращения проблем со специфичностью CSS.

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

import { makeStyles } from '@griffel/react';

const useClasses = makeStyles({
button: { color: 'red' },
icon: { paddingLeft: '5px' },
});

function Component() {
const classes = useClasses();

return (
<div>
<button className={classes.button} />
<span className={classes.icon} />
</div>
);
}

При написании стилей поддерживаются псевдоклассы, псевдоэлементы и at-правила. Также в Griffel есть API для создания глобальных стилей, которые не привязаны к компоненту – makeStaticStyles.

https://github.com/microsoft/griffel

Очень интересно наблюдать, как появляются новые CSS-in-JS библиотеки, особенно от таких крупных компаний. Еще в 2019 году Facebook рассказал о своей CSS-in-JS библиотеке – Stylex. Правда она еще до сих пор не появилась на гитхабе.
👍7👎3
Релиз версии Next.js 12.1

Произошел релиз Next.js 12.1 с одной из самых востребованных фич – Incremental Static Regeneration (ISR). ISR позволяет создавать и обновлять статические страницы сайта после сборки проекта. Обновление статической страницы возможно двумя способами. Обновить статическую страницу можно автоматически, спустя заданное количество секунд после последней генерации страницы:

export async function getStaticProps() {
return {
// Next.js will attempt to re-generate the page:
// - When a request comes in
// - At most once every 10 seconds
revalidate: 10, // In seconds
}
}

Также возможно ручное обновление страницы. Например, такое пригодится для интернет-магазинов, при изменении цены товара на странице:

// pages/api/revalidate.js
export default async function handler(req, res) {
// Check for secret to confirm this is a valid request
if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
return res.status(401).json({ message: 'Invalid token' })
}

try {
await res.unstable_revalidate('/path-to-revalidate')
return res.json({ revalidated: true })
} catch (err) {
// If there was an error, Next.js will continue
// to show the last successfully generated page
return res.status(500).send('Error revalidating')
}
}


Другие изменения в новой версии:
- Улучшена поддержка SWC. Некоторые Babel плагины были портированы на Rust. Включена поддержка styled-components, relay.
- Автоматическая конфигурация Jest.
- Более быстрая минификация, используя SWC. В 7 раз быстрее чем Terser.
- Оптимизация изображений. API по работе с изображениями поддерживает паттерн ISR.
- Работа в сторону поддержки React 18, серверных компонентов и потокового SSR. Была обновлена документация для тех, кто хочет попробовать эти фичи.

https://nextjs.org/blog/next-12-1
👍7
Доступен React 18 RC

Версия React 18 стала доступна в качестве релиз-кандидата. Чтобы установить, нужно использовать @rc тег:

npm install react@rc react-dom@rc
// или
yarn add react@rc react-dom@rc


В React 18 появится новое API для библиотек. Для поддержки конкурентного рендеринга сторонними библиотеками было добавлено следующее API:
- useId – хук для генерации уникального id на клиенте и сервере, поддерживающего гидратацию. Подробнее.
- useSyncExternalStore – хук для работы с внешними хранилищами, позволяющий производить параллельное чтение из источника и синхронную запись. Подробнее.
- useInsertionEffect – хук для вставки стилей в процессе рендера, предназначен для CSS-in-JS библиотек. Подробнее.

Новые изменения в строгом режиме (strict mode). В будущем React планирует поддерживать пользовательский UI, в котором части интерфейса можно будет удалить с сохранением стейта, чтобы потом их можно было восстановить. Например, переключение табов на странице, когда при смене таба нужный компонент будет отображаться сразу с восстановленным состоянием.

Для поддержки такого UI сценария React добавляет новую проверку в development режиме в strict mode. Эта новая проверка будет автоматически демонтировать и повторно монтировать каждый компонент всякий раз, когда компонент монтируется в первый раз, восстанавливая предыдущее состояние при втором монтировании.

Также в React 18 прекращается поддержка браузера Internet Explorer.

https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html
👍7
История React

На канале uidotdev вышло видео об истории React, о том как он возник в 2013 году и стал тем, чем является сейчас.

https://www.youtube.com/watch?v=Wm_xI7KntDs
👍3
Структура проекта React от Джошуа Комо

В React нет единого подхода к организации структуры проекта, поэтому у многих начинающих разработчиков возникает вопрос, как правильно? Один из советов Дэна Абрамова – “перемещайте файлы, пока не почувствуете, что это правильно”.

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

https://www.joshwcomeau.com/react/file-structure/
👎15👍9
Как проектировалось мидлвар подписки для Redux Toolkit

В Redux Toolkit 1.8 вышло новое API createListenerMiddleware для подписки на отправку экшенов или изменения стейта. Это API должно стать более простой альтернативой использования вместо более популярных saga или observable.

// Create the middleware instance and methods
const listenerMiddleware = createListenerMiddleware()

// Add one or more listener entries that look for specific actions.
// They may contain any sync or async logic, similar to thunks.
listenerMiddleware.startListening({
actionCreator: todoAdded,
effect: async (action, listenerApi) => {
// Run whatever additional side-effect-y logic you want here
console.log('Todo added: ', action.payload.text)

// Can cancel other running instances
listenerApi.cancelActiveListeners()

// Run async logic
const data = await fetchData()

// Pause until action dispatched or state changed
if (await listenerApi.condition(matchSomeAction)) {
// Use the listener API methods to dispatch, get state,
// unsubscribe the listener, start child tasks, and more
listenerApi.dispatch(todoAdded('Buy pet food'))
listenerApi.unsubscribe()
}
},
})

В своем блоге один из разработчиков Redux Toolkit, Марк Эриксон, рассказал об истории данного API и этапах его разработки. Разработка данной фичи была начата 2.5 года назад и потребовала много итераций, чтобы определить, какие варианты использования он должен охватывать, как должен выглядеть общедоступный API и как реализовать функциональность.

В основе у Redux есть несколько основных библиотек для работы с сайд эффектами:
- Thunks: отправить экшен, получить (dispatch, getState) в аргументах и выполнить любую логику внутри функции.
- Sagas: напишите функцию генератор, которая на экшен вызывает сайд эффект функцию.
- Observables: напишите RxJs пайплайн, который на экшен вызывает сайд эффект функцию.

По умолчанию в Redux Toolkit был выбран Thunks, как самый простой вариант работы с сайд эффектами. При разработке API createListenerMiddleware команда Redux Toolkit хотела отделить экшены и сайд эффекты, т.е. смотрела в сторону redux-saga. Однако по сложности пользовательского API была цель сделать его близким к redux-thunk.

https://blog.isquaredsoftware.com/2022/03/designing-rtk-listener-middleware/
👍5
Тинькофф представил React фреймворк tramvai

Компания Тинькофф выложила в opensource свой React фреймворк для создания SSR приложений tramvai. Фреймворк похож на node.js фреймворк Nest.js, в нем также есть DI и модули.

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

Выглядит очень необычно. Будет ли пользоваться спросом данный фреймворк где-то за пределами проектов Тинькофф – вопрос интересный.

https://tramvai.dev/
https://habr.com/ru/post/655953/
👍14👎1