This media is not supported in your browser
VIEW IN TELEGRAM
Эффект ввода текста с помощью React
В своем блоге Жюльен Тибо показал, как создать эффект ввода текста с помощью хука на React. Его можно использовать при создании чатов как анимацию загрузки или просто добавить динамики на сайт.
https://www.julienthibeaut.xyz/blog/create-text-typing-effect-with-react
В своем блоге Жюльен Тибо показал, как создать эффект ввода текста с помощью хука на React. Его можно использовать при создании чатов как анимацию загрузки или просто добавить динамики на сайт.
const useTypingEffect = (
text: string,
duration: number,
isTypeByLetter = false
) => {
const [currentPosition, setCurrentPosition] = useState(0);
const items = isTypeByLetter ? text.split("") : text.split(" ");
useEffect(() => {
setCurrentPosition(0);
}, [text]);
useEffect(() => {
if (currentPosition >= items.length) return;
const intervalId = setInterval(() => {
setCurrentPosition((prevPosition) => prevPosition + 1);
}, duration);
return () => {
clearInterval(intervalId);
};
}, [currentPosition, items, duration]);
return items.slice(0, currentPosition).join(isTypeByLetter ? "" : " ");
};
https://www.julienthibeaut.xyz/blog/create-text-typing-effect-with-react
👍12❤1
Лучшие практики создания форм с react-hook-form
Обзор лучших практик создания больших форм с использованием react-hook-form и TypeScript:
1. Разделите форму на несколько небольших компонентов. Например, если форма состоит из нескольких секций, то вынесите каждую секцию в отдельный компонент.
2. Используйте пропы value и onChange для ввода и вывода для кастомных компонентов. Такой подход позволит бесшовно интегрировать react-hook-form.
3. Используйте проп name у полей формы для идентификации полей.
4. Используйте кастомный хук для типизации контекста формы:
import { useFormContext } from 'react-hook-form';
export const useMyFormContext = () => useFormContext<MyFormInterface>();
https://orizens.com/blog/best_practices_for_developing_complex_form-based_apps_with_react_hook_form_and_typenoscript_support/
Обзор лучших практик создания больших форм с использованием react-hook-form и TypeScript:
1. Разделите форму на несколько небольших компонентов. Например, если форма состоит из нескольких секций, то вынесите каждую секцию в отдельный компонент.
2. Используйте пропы value и onChange для ввода и вывода для кастомных компонентов. Такой подход позволит бесшовно интегрировать react-hook-form.
3. Используйте проп name у полей формы для идентификации полей.
4. Используйте кастомный хук для типизации контекста формы:
import { useFormContext } from 'react-hook-form';
export const useMyFormContext = () => useFormContext<MyFormInterface>();
https://orizens.com/blog/best_practices_for_developing_complex_form-based_apps_with_react_hook_form_and_typenoscript_support/
Orizens
Best Practices for Developing Complex Form-Based Apps with React Hook Form and TypeScript Support - Oren Farhi
👍8
Sugar High – легковесная подсветка кода
Sugar High - это легковесная подсветка кода на JSX, которая весит 1КБ после минификации и сжатия. Есть возможность кастомизации: можно поменять цвета токенов через CSS переменные.
https://sugar-high.vercel.app/
Sugar High - это легковесная подсветка кода на JSX, которая весит 1КБ после минификации и сжатия. Есть возможность кастомизации: можно поменять цвета токенов через CSS переменные.
https://sugar-high.vercel.app/
👍11
Тестирование своих библиотек локально с помощью Yalc
При разработке библиотеки возникает необходимость проверить локально его работу. Обычно используют npm link или выкладывают в npm альфа-версию. Оба варианта не идеальные, например, при npm link могут возникнуть ошибки из-за несоответствия версий React в библиотеке и в приложении.
Yalc решает проблему локального тестирования библиотек и делает это довольно просто. Используйте команду yalc publish для публикации библиотеки и yalc add my-package в приложении, где хотите протестировать библиотеку.
https://github.com/wclr/yalc
При разработке библиотеки возникает необходимость проверить локально его работу. Обычно используют npm link или выкладывают в npm альфа-версию. Оба варианта не идеальные, например, при npm link могут возникнуть ошибки из-за несоответствия версий React в библиотеке и в приложении.
Yalc решает проблему локального тестирования библиотек и делает это довольно просто. Используйте команду yalc publish для публикации библиотеки и yalc add my-package в приложении, где хотите протестировать библиотеку.
https://github.com/wclr/yalc
GitHub
GitHub - wclr/yalc: Work with yarn/npm packages locally like a boss.
Work with yarn/npm packages locally like a boss. Contribute to wclr/yalc development by creating an account on GitHub.
👍12❤1
Апдейт по компилятору React Forget
Сатья Гунасекаран, член основной команды React, рассказал почему затянулось создание компилятора React Forget и насколько он сложнее чем задумывался.
Компилятор будет поддерживать весь JavaScript, включая все его особенности. React Forget будет обратно совместим, поэтому приходится работать с существующим кодом, что усложняет задачу.
Есть задачи, которые на первый взгляд кажутся простыми, но на деле гораздо сложнее – это алиасы. Например, если создать алиас и присвоить переменную x другой переменной y:
Для компилятора есть вариант запомнить вычисление x отдельно и сделать его зависимостью для y:
Однако, правильным способом компиляции будет объединение этих вычислений в группу под одним useMemo:
Этот пример довольно простой. А теперь представьте, что между x и y добавится поток управления или вызов функции, тогда такой код добавит еще больше сложности для анализа компилятору.
https://www.reddit.com/r/reactjs/comments/16nnh4z/comment/k1jbr4t/
Сатья Гунасекаран, член основной команды React, рассказал почему затянулось создание компилятора React Forget и насколько он сложнее чем задумывался.
Компилятор будет поддерживать весь JavaScript, включая все его особенности. React Forget будет обратно совместим, поэтому приходится работать с существующим кодом, что усложняет задачу.
Есть задачи, которые на первый взгляд кажутся простыми, но на деле гораздо сложнее – это алиасы. Например, если создать алиас и присвоить переменную x другой переменной y:
function Component({a, b}) {
const x = [];
x.push(a);
const y = x;
y.push(b);
return <Foo x={x}/>;
}
Для компилятора есть вариант запомнить вычисление x отдельно и сделать его зависимостью для y:
// Неправильно
function Component({a, b}) {
const x = useMemo(() => {
const x = [];
x.push(a);
return x;
}, [a]);
const y = useMemo(() => {
const y = x;
y.push(b);
return y;
}, [x, b])
return <Foo x={x}/>;
}
Однако, правильным способом компиляции будет объединение этих вычислений в группу под одним useMemo:
function Component({a, b}) {
const x = useMemo(() => {
const x = [];
x.push(a);
const y = x;
y.push(b);
return y;
}, [a, b]);
return <Foo x={x}/>;
}
Этот пример довольно простой. А теперь представьте, что между x и y добавится поток управления или вызов функции, тогда такой код добавит еще больше сложности для анализа компилятору.
https://www.reddit.com/r/reactjs/comments/16nnh4z/comment/k1jbr4t/
❤3👍3
Интеграция веб-компонентов и React
Библиотека @lit/react позволяет безболезненно интегрировать веб-компоненты в React. Основная проблема при интеграции веб-компонентов в React – передача пропсов и прием событий. Данная библиотека решает эту проблему через функцию createComponent, которая мапит пропсы в веб-компонент.
Например, чтобы принимать событие onfoo нужно передать объект {onfoo: 'foo'}. Это означает, что событие onfoo будет вызываться каждый раз, когда кастомный элемент отправляет событие foo.
Пример интеграции веб-компонента и мапинг событий:
Пример использования компонента в React:
https://www.npmjs.com/package/@lit/react
Библиотека @lit/react позволяет безболезненно интегрировать веб-компоненты в React. Основная проблема при интеграции веб-компонентов в React – передача пропсов и прием событий. Данная библиотека решает эту проблему через функцию createComponent, которая мапит пропсы в веб-компонент.
Например, чтобы принимать событие onfoo нужно передать объект {onfoo: 'foo'}. Это означает, что событие onfoo будет вызываться каждый раз, когда кастомный элемент отправляет событие foo.
Пример интеграции веб-компонента и мапинг событий:
import * as React from 'react';
import {createComponent} from '@lit/react';
import {MyElement} from './my-element.js';
export const MyElementComponent = createComponent({
tagName: 'my-element',
elementClass: MyElement,
react: React,
events: {
onactivate: 'activate',
onchange: 'change',
},
});
Пример использования компонента в React:
<MyElementComponent
active={isActive}
onactivate={(e) => (isActive = e.active)}
/>
https://www.npmjs.com/package/@lit/react
npm
npm: @lit/react
A React component wrapper for web components.. Latest version: 1.0.8, last published: 2 months ago. Start using @lit/react in your project by running `npm i @lit/react`. There are 343 other projects in the npm registry using @lit/react.
👍10
Гайд по серверным компонентам
servercomponents.dev – сайт с гайдами по серверным компонентам, в которых объясняется, что это такое, чем это отличается от других решений и как этим пользоваться.
Основная информация для сайта была взята из разных источников, например из подкаста JavaScript Jabber, где Дэн Абрамов и Джо Савона обсуждали серверные компоненты в React. Причина этого в том, что на сайте документации react.dev отсутствует подробная информация про серверные компоненты, поэтому информацию про нее приходится искать в разных источниках.
Автор написал на следующие темы:
- Что такое серверные компоненты и чем они отличаются?
- Какую проблему решают серверные компоненты?
- Поэтапное внедрение серверных компонентов?
https://servercomponents.dev/
servercomponents.dev – сайт с гайдами по серверным компонентам, в которых объясняется, что это такое, чем это отличается от других решений и как этим пользоваться.
Основная информация для сайта была взята из разных источников, например из подкаста JavaScript Jabber, где Дэн Абрамов и Джо Савона обсуждали серверные компоненты в React. Причина этого в том, что на сайте документации react.dev отсутствует подробная информация про серверные компоненты, поэтому информацию про нее приходится искать в разных источниках.
Автор написал на следующие темы:
- Что такое серверные компоненты и чем они отличаются?
- Какую проблему решают серверные компоненты?
- Поэтапное внедрение серверных компонентов?
https://servercomponents.dev/
servercomponents.dev
ServerComponents.dev | What are RSCs
An outline of React Server Components, what they are, why they're here, and how to use them conceptually.
👍15
Релиз TanStack Query v5
Вышел релиз библиотеки TanStack Query v5 (react-query). Новая версия меньше предыдущей на 20% и более интуитивно понятна.
Критические изменения:
- Удалено большинство перегрузок функций и унифицировано использование useQuery и других хуков.
- Переименован параметр cacheTime на gcTime.
- Объединены keepPreviousData и placeholderData.
- Переименован loading в pending.
- Удалены колбеки из useQuery.
Новые фичи:
- Упрощение оптимистических изменений. Хук useMutation возвращает переданные аргументы в variables.
- Полная поддержка suspense. Появились хуки useSuspenseQuery, useSuspenseInfiniteQuery и useSuspenseQueries.
- Возможность предзагрузки нескольких страниц в Infinity Query с помощью prefetchInfiniteQuery.
- Новый DevTools.
https://tanstack.com/blog/announcing-tanstack-query-v5
Вышел релиз библиотеки TanStack Query v5 (react-query). Новая версия меньше предыдущей на 20% и более интуитивно понятна.
Критические изменения:
- Удалено большинство перегрузок функций и унифицировано использование useQuery и других хуков.
- Переименован параметр cacheTime на gcTime.
- Объединены keepPreviousData и placeholderData.
- Переименован loading в pending.
- Удалены колбеки из useQuery.
Новые фичи:
- Упрощение оптимистических изменений. Хук useMutation возвращает переданные аргументы в variables.
- Полная поддержка suspense. Появились хуки useSuspenseQuery, useSuspenseInfiniteQuery и useSuspenseQueries.
- Возможность предзагрузки нескольких страниц в Infinity Query с помощью prefetchInfiniteQuery.
- Новый DevTools.
https://tanstack.com/blog/announcing-tanstack-query-v5
Tanstack
Announcing TanStack Query v5 | TanStack Blog
About one year ago, we announced the , and the whole team has been working hard on that version ever since. So we're super happy to announce that today is the day: After 91 alpha releases, 35 betas an...
🔥13👍5
Тонкости работы useTransition
В React появился хук useTransition, который позволяет делает UI переходы без зависаний. Хук возвращает флаг «загрузки» перехода и функцию для запуска перехода. Изменение стейта, вызванное в функции запуска перехода, выполняется в «фоне», пока нет активных критических изменений стейта.
Надя Макаревич сделала пример использования useTransition и показала с какой проблемой производительности можно столкнуться. В качестве примера рассматривается компонент с табами. Один из табов – тяжелый компонент, который долго рендерится. Если не использовать useTransition, то при переключении на тяжелый компонент UI фризится до окончания рендера. Если использовать useTransition, то UI не фризится, но возникает другая проблема: когда переключаемся на таб тяжелого компонента, а после на другой таб, то переключение будет занимать больше времени.
Дело в том, что хук useTransition возвращает два аргумента, первый из которых это флаг «загрузки» перехода. Когда мы вызываем функцию перехода, то происходит ре-рендер компонента с текущим состоянием, т.к. флаг «загрузки» перехода становится true. Из-за этого могут возникнуть проблемы с производительностью приложения. Чтобы избежать этого, используйте мемоизацию компонентов и их пропсов.
https://www.developerway.com/posts/use-transition
В React появился хук useTransition, который позволяет делает UI переходы без зависаний. Хук возвращает флаг «загрузки» перехода и функцию для запуска перехода. Изменение стейта, вызванное в функции запуска перехода, выполняется в «фоне», пока нет активных критических изменений стейта.
const [isPending, startTransition] = useTransition();
// …
<TabButton
isLoading={isPending}
onClick={() => {
startTransition(() => {
setTab('projects');
});
}}
/>
Надя Макаревич сделала пример использования useTransition и показала с какой проблемой производительности можно столкнуться. В качестве примера рассматривается компонент с табами. Один из табов – тяжелый компонент, который долго рендерится. Если не использовать useTransition, то при переключении на тяжелый компонент UI фризится до окончания рендера. Если использовать useTransition, то UI не фризится, но возникает другая проблема: когда переключаемся на таб тяжелого компонента, а после на другой таб, то переключение будет занимать больше времени.
Дело в том, что хук useTransition возвращает два аргумента, первый из которых это флаг «загрузки» перехода. Когда мы вызываем функцию перехода, то происходит ре-рендер компонента с текущим состоянием, т.к. флаг «загрузки» перехода становится true. Из-за этого могут возникнуть проблемы с производительностью приложения. Чтобы избежать этого, используйте мемоизацию компонентов и их пропсов.
https://www.developerway.com/posts/use-transition
Developerway
React useTransition: performance game changer or...?
Looking into what React Concurrent Rendering is, what hooks like useTransition and useDeferredValue do, what are the benefits and downsides of using them.
🔥5👍3
Как оптимизировали импорт пакетов в Next.js
В релизе Next.js 13.5 рассказали, что оптимизировали импорт пакетов. Это улучшило скорость локальной разработки и холодный запуск прод сборки, когда использовались пакеты, которые реэкспортировали большое количество модулей в баррель файле, например, иконки и UI библиотеки.
Если вы хотите импортировать один модуль из баррель-файла, который реэкспортирует тысячи модулей, то в сборку попадут все тысячи модулей. Для решения данной проблемы, сборщики используют три-шейкинг.
Первой попыткой оптимизировать импорт пакетов в Next.js был modularizeImports. Это опция позволяла настроить маппинг между именем экспорта и расположением его файла. То есть при компиляции проекта import { module2 } from 'my-lib’ превращался в import module2 from 'my-lib/module2’.
Проблема этого подхода была в том, что оптимизация ломалась, когда менялась внутренняя структура пакета. Для решения проблемы ввели новую опцию – optimizePackageImports, с помощью которой Next.js автоматически сам замапит имена экспортов и расположение файла с помощью предзаписанного списка популярных библиотек. Этот список библиотек со временем будет расширяться.
https://vercel.com/blog/how-we-optimized-package-imports-in-next-js
В релизе Next.js 13.5 рассказали, что оптимизировали импорт пакетов. Это улучшило скорость локальной разработки и холодный запуск прод сборки, когда использовались пакеты, которые реэкспортировали большое количество модулей в баррель файле, например, иконки и UI библиотеки.
Если вы хотите импортировать один модуль из баррель-файла, который реэкспортирует тысячи модулей, то в сборку попадут все тысячи модулей. Для решения данной проблемы, сборщики используют три-шейкинг.
Первой попыткой оптимизировать импорт пакетов в Next.js был modularizeImports. Это опция позволяла настроить маппинг между именем экспорта и расположением его файла. То есть при компиляции проекта import { module2 } from 'my-lib’ превращался в import module2 from 'my-lib/module2’.
Проблема этого подхода была в том, что оптимизация ломалась, когда менялась внутренняя структура пакета. Для решения проблемы ввели новую опцию – optimizePackageImports, с помощью которой Next.js автоматически сам замапит имена экспортов и расположение файла с помощью предзаписанного списка популярных библиотек. Этот список библиотек со временем будет расширяться.
https://vercel.com/blog/how-we-optimized-package-imports-in-next-js
Telegram
Заметки про React
Релиз Next.js 13.5
Вышел релиз Next.js 13.5. Список изменений:
- Запуск dev сервера на 22% быстрее для App и Pages Router.
- HMR работает на 29% быстрее.
- Уменьшение потребления памяти сервера на 40%.
- Пофикшены более 438 багов.
- Оптимизированный импорт…
Вышел релиз Next.js 13.5. Список изменений:
- Запуск dev сервера на 22% быстрее для App и Pages Router.
- HMR работает на 29% быстрее.
- Уменьшение потребления памяти сервера на 40%.
- Пофикшены более 438 багов.
- Оптимизированный импорт…
👍7
Rspress – генератор статических сайтов на Rspack
Команда ByteDance представила стабильную версию Rspress – генератора статических сайтов для документации. Под капотом использует Rspack – сборщик, написанный на Rust. Основные фичи генератора:
- Скорость сборки и HMR. Гораздо быстрее своих конкурентов.
- Поддержка MDX, а значит можно вставлять React компоненты в разметку.
- Встроенный полнотекстовый поиск на основе FlexSearch.
- Встроенная поддержка i18n и версионирования.
- Возможность кастомизации темы и сборки.
Основные конкуренты – Docusaurus, Nextra от Vercel и Vitepress.
https://rspress.dev/
Команда ByteDance представила стабильную версию Rspress – генератора статических сайтов для документации. Под капотом использует Rspack – сборщик, написанный на Rust. Основные фичи генератора:
- Скорость сборки и HMR. Гораздо быстрее своих конкурентов.
- Поддержка MDX, а значит можно вставлять React компоненты в разметку.
- Встроенный полнотекстовый поиск на основе FlexSearch.
- Встроенная поддержка i18n и версионирования.
- Возможность кастомизации темы и сборки.
Основные конкуренты – Docusaurus, Nextra от Vercel и Vitepress.
https://rspress.dev/
👍6
Релиз Next.js 14
Вышел релиз Next.js 14. Основные изменения:
- Улучшение в Turbopack. Сборщик, написанный на Rust, стал на 53% быстрее запускаться и на 94% быстрее работать HMR.
- Серверные действия. Появилась возможность в компоненте на клиенте вызывать серверные действия внутри функции:
Next.js сам разделит код на клиентский и серверный. Если используете TypeScript, то эта фича обеспечит полную сквозную безопасность типов между сервером и клиентом.
Также в серверных действиях можно ревалидировать кэш, делать редирект, читать и устанавливать куки. То есть можно делать практически все то же самое, что и в обычном серверном API.
- Частичный пререндер. Появилась возможность частичного пререндера страницы с помощью Suspense. Например:
С частичным пререндером Next.js сгенерит статическую оболочку (shell) страницы, а вместо Suspense подставит fallback. Затем вместо fallback подставится динамический компонент, который пререндерится на сервере и стримится клиенту через тот же HTTP запрос, что и статическая оболочка.
- Улучшение метаданных
Появилась опция управлять мета-тегом viewport, colorScheme и themeColor через переменную viewport или функцию generateViewport:
https://nextjs.org/blog/next-14
Вышел релиз Next.js 14. Основные изменения:
- Улучшение в Turbopack. Сборщик, написанный на Rust, стал на 53% быстрее запускаться и на 94% быстрее работать HMR.
- Серверные действия. Появилась возможность в компоненте на клиенте вызывать серверные действия внутри функции:
export default function Page() {
async function create(formData: FormData) {
'use server';
const id = await createItem(formData);
}
return (
<form action={create}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
);
}
Next.js сам разделит код на клиентский и серверный. Если используете TypeScript, то эта фича обеспечит полную сквозную безопасность типов между сервером и клиентом.
Также в серверных действиях можно ревалидировать кэш, делать редирект, читать и устанавливать куки. То есть можно делать практически все то же самое, что и в обычном серверном API.
- Частичный пререндер. Появилась возможность частичного пререндера страницы с помощью Suspense. Например:
export default function Page() {
return (
<main>
<header>
<h1>My Store</h1>
<Suspense fallback={<CartSkeleton />}>
<ShoppingCart />
</Suspense>
</header>
{/* --snip-- */}
</main>
);
}
С частичным пререндером Next.js сгенерит статическую оболочку (shell) страницы, а вместо Suspense подставит fallback. Затем вместо fallback подставится динамический компонент, который пререндерится на сервере и стримится клиенту через тот же HTTP запрос, что и статическая оболочка.
- Улучшение метаданных
Появилась опция управлять мета-тегом viewport, colorScheme и themeColor через переменную viewport или функцию generateViewport:
export const viewport: Viewport = {
themeColor: 'black',
}
export default function Page() {}
https://nextjs.org/blog/next-14
nextjs.org
Next.js 14
Next.js 14 includes included performance, stability for Server Actions, a new course teaching the App Router, and more.
❤12🔥7👍6
Оптимизация производительности браузерного расширения
Гайд по оптимизации браузерного расширения на React от Casca. Какие шаги команда предприняла:
- Оптимизация изображений. Чтобы не показывать пользователю тяжелые изображения, использовали Node.js библиотеку sharp для оптимизации и уменьшения изображений. Это увеличивает скорость загрузки изображений и уменьшает потребление памяти RAM.
- Кэширование запросов локально для работы в автономном режиме.
- Предотвращение повторных ре-рендеров. Использование useMemo и реализации useEvent для мемоизации пропсов. Также реализовали свою библиотеку, работающую с массивом данных – keep-unchanged-values. Она предотвращает ререндеры, сохраняя неизмененные значения и обновляя только измененные данные.
https://cascaspace.substack.com/p/optimizing-performance-how-our-extension
Гайд по оптимизации браузерного расширения на React от Casca. Какие шаги команда предприняла:
- Оптимизация изображений. Чтобы не показывать пользователю тяжелые изображения, использовали Node.js библиотеку sharp для оптимизации и уменьшения изображений. Это увеличивает скорость загрузки изображений и уменьшает потребление памяти RAM.
- Кэширование запросов локально для работы в автономном режиме.
- Предотвращение повторных ре-рендеров. Использование useMemo и реализации useEvent для мемоизации пропсов. Также реализовали свою библиотеку, работающую с массивом данных – keep-unchanged-values. Она предотвращает ререндеры, сохраняя неизмененные значения и обновляя только измененные данные.
https://cascaspace.substack.com/p/optimizing-performance-how-our-extension
Casca’s Substack
Optimizing Performance: How Our Extension Became Lightning Fast
Discover how we made our browser extension faster. Find out about the technologies and strategies we used to improve performance and provide a smooth browsing experience.
👍5
Погружение в Storybook
Команда Formidable рассказала, как они работают со Storybook. Обычно принято использовать Storybook как витрину UI компонентов. Кроме этого, Storybook можно использовать для локальной разработки сложных UI компонентов и проведения визуального тестирования.
При работе со Storybook есть одна из сложностей – управление зависимостями компонентов, например контекст, CSS стили, работа сторонних скриптов. Для решения проблемы можно создать компонент-обертку, который будет настраивать окружение для компонентов. Например:
В Storybook есть встроенная возможность визуального тестирования. В чем его преимущества:
- Нет необходимости в дополнительной настройке окружения для тестирования.
- Можно визуально увидеть работу тестов и использовать браузерную консоль и отладчик.
- Работает браузерное API и внедрить тестирование гораздо проще, чем использовать сторонние библиотеки.
Как это работает: у каждой Story есть функция play, внутри которой можно взаимодействовать со Story и выполнять проверки. Функция play выполняется при открытии Story и можно визуально увидеть ее работу. Пример:
https://formidable.com/blog/2023/unlocking-the-power-of-storybook/
Команда Formidable рассказала, как они работают со Storybook. Обычно принято использовать Storybook как витрину UI компонентов. Кроме этого, Storybook можно использовать для локальной разработки сложных UI компонентов и проведения визуального тестирования.
При работе со Storybook есть одна из сложностей – управление зависимостями компонентов, например контекст, CSS стили, работа сторонних скриптов. Для решения проблемы можно создать компонент-обертку, который будет настраивать окружение для компонентов. Например:
export const TestHarness = ({ children, route = "/", cart = {} }) => {
return (
<MemoryRouter initialEntries={[route]}>
<CartContext.Provider value={{ ...emptyCart, ...cart }}>
{children}
</CartContext.Provider>
</MemoryRouter>
);
};
Использовать его можно как декоратор:
// ~/.storybook/preview.ts
export const decorators = [
(Story, ctx) => <TestHarness {...ctx.parameters}><Story /></TestHarness>
];
В Storybook есть встроенная возможность визуального тестирования. В чем его преимущества:
- Нет необходимости в дополнительной настройке окружения для тестирования.
- Можно визуально увидеть работу тестов и использовать браузерную консоль и отладчик.
- Работает браузерное API и внедрить тестирование гораздо проще, чем использовать сторонние библиотеки.
Как это работает: у каждой Story есть функция play, внутри которой можно взаимодействовать со Story и выполнять проверки. Функция play выполняется при открытии Story и можно визуально увидеть ее работу. Пример:
// ~/components/Search.stories.tsx
export const WithSearchTerm: Story = {
async play({ canvasElement, step }) {
const ui = wrap(canvasElement); // The `wrap` function is defined later in this article
await step("type 'baguette' into the search box", async () => {
ui.searchbox.focus();
await userEvent.type(ui.searchbox, "baguette");
});
},
};
https://formidable.com/blog/2023/unlocking-the-power-of-storybook/
Storybook
Integrations | Storybook: Frontend workshop for UI development
Integrations enable advanced functionality and unlock new workflows. Contributed by core maintainers and the amazing developer community.
🔥12👍4
Создание игровых интерфейсов с помощью React
Для разработки игровых интерфейсов гораздо удобнее использовать экосистему React, HTML и CSS, чем делать это с помощью Unity. Например, Minecraft и Battlefield в той или иной форме используют React для своих игровых интерфейсов.
Есть два способа использовать React.
- Встраивание браузера или Webview. Если игра на ПК, то будет встраиваться Chromium. Если этот способ сильно утяжеляет игру, то можно воспользоваться Coherent Gameface. Это облегченная версия браузера, адаптированная к игровым UI и его можно использовать в Unity и Unreal Engine.
- Безбраузерный подход. Этот подход пропускает браузерный рендеринг и сразу интерпретирует JS в нативный UI код игрового движка. Наиболее полноценная библиотека для этого – OneJS. Он спроектирован для Unitiy и поддерживает TypeScript и Preact. Этот вариант работает более быстро, чем браузерный подход, но у него есть свои ограничения. Нельзя использовать сторонние библиотеки, Canvas, SVG и сложные CSS анимации.
https://www.adammadojemu.com/blog/intro-to-building-game-uis-with-react
Для разработки игровых интерфейсов гораздо удобнее использовать экосистему React, HTML и CSS, чем делать это с помощью Unity. Например, Minecraft и Battlefield в той или иной форме используют React для своих игровых интерфейсов.
Есть два способа использовать React.
- Встраивание браузера или Webview. Если игра на ПК, то будет встраиваться Chromium. Если этот способ сильно утяжеляет игру, то можно воспользоваться Coherent Gameface. Это облегченная версия браузера, адаптированная к игровым UI и его можно использовать в Unity и Unreal Engine.
- Безбраузерный подход. Этот подход пропускает браузерный рендеринг и сразу интерпретирует JS в нативный UI код игрового движка. Наиболее полноценная библиотека для этого – OneJS. Он спроектирован для Unitiy и поддерживает TypeScript и Preact. Этот вариант работает более быстро, чем браузерный подход, но у него есть свои ограничения. Нельзя использовать сторонние библиотеки, Canvas, SVG и сложные CSS анимации.
https://www.adammadojemu.com/blog/intro-to-building-game-uis-with-react
Adammadojemu
An Intro to Building Game UIs with React
A deep dive into the fusion of web development and game development. This article touches on React's uses within game UIs, industry giants taking the React route, and the two predominant strategies for incorporating React in game development.
👍6❤1
Headless компонент: паттерн в React
В блоге Мартина Фаулера вышла статья от инженера Atlassian о паттерне Headless компонента.
Headless компонент – это компонент, который обычно реализован в виде React хуков и отвечает исключительно за логику и управление состоянием. По сути он предоставляет функционал без UI.
При визуализации Headless компонент выглядит как тонкий слой по середине между UI и моделью данных.
Этот подход уже используется в нескольких библиотеках: React ARIA, Headless UI, React Table и Downshift.
В своей статье Цзюньтао Цю рассказал, как пошагово создать Headless компонент для элемента Dropdown, подключить его к UI и написать тесты.
https://martinfowler.com/articles/headless-component.html
В блоге Мартина Фаулера вышла статья от инженера Atlassian о паттерне Headless компонента.
Headless компонент – это компонент, который обычно реализован в виде React хуков и отвечает исключительно за логику и управление состоянием. По сути он предоставляет функционал без UI.
При визуализации Headless компонент выглядит как тонкий слой по середине между UI и моделью данных.
Этот подход уже используется в нескольких библиотеках: React ARIA, Headless UI, React Table и Downshift.
В своей статье Цзюньтао Цю рассказал, как пошагово создать Headless компонент для элемента Dropdown, подключить его к UI и написать тесты.
https://martinfowler.com/articles/headless-component.html
martinfowler.com
Headless Component: a pattern for composing React UIs
Separates state management logic from the visual representation
👍16
Генерация SourceMap для артефактов прод сборки React
В React были смержены изменения, в которых добавилась генерация SourceMap для артефактов прод сборки React, таких как react-dom.production.min.js.
Это означает, что при отладке проблем на проде, код React будет читаемым, поэтому будет проще читать стектрейс ошибки. Также, это улучшит опыт работы с инструментами для анализа ошибок, например с Replay.
https://github.com/facebook/react/pull/26446
В React были смержены изменения, в которых добавилась генерация SourceMap для артефактов прод сборки React, таких как react-dom.production.min.js.
Это означает, что при отладке проблем на проде, код React будет читаемым, поэтому будет проще читать стектрейс ошибки. Также, это улучшит опыт работы с инструментами для анализа ошибок, например с Replay.
https://github.com/facebook/react/pull/26446
GitHub
Generate sourcemaps for production build artifacts by markerikson · Pull Request #26446 · facebook/react
Summary
This PR updates the Rollup build pipeline to generate sourcemaps for production build artifacts like react-dom.production.min.js.
It requires the Rollup v3 changes that were just merged in ...
This PR updates the Rollup build pipeline to generate sourcemaps for production build artifacts like react-dom.production.min.js.
It requires the Rollup v3 changes that were just merged in ...
👍17
React memo на самом деле хорош
Тимоти Пиллард в своем блоге собрал список наиболее популярных заблуждений о мемоизации в React и объяснил, почему он с этим не согласен. Речь идет о React.memo, React.useMemo, React.useCallback. Кратко о чем он написал:
- «React в любом случае настолько быстр, что React.memo не нужен». В большинстве кейсов React действительно быстрый. API мемоизации существует, чтобы заполнить пробел в модели рендеринга React.
Производительность приложения зависит от множества факторов, а проблемы производительности React приложения в большинстве случаев можно решить с помощью сочетания архитектурных паттернов, рефакторинга и разных инструментов, включая React.memo.
- «React.memo контрпродуктивен». React.memo может быть контрпродуктивным, если им неправильно пользоваться, например, если компонент постоянно получает разные пропсы, то это сделает мемоизацию неэффективной, т.к. повлечет за собой ненужные сравнения.
- «React.memo не работает с пропсом children». Эта проблема происходит из-за того, что React создает элемент через вызов React.createElement(…), который постоянно возвращает новый объект. Этого не произойдет, если передавать в children переменную с элементом, объявленную вне функции компонента, пример:
https://timtech.blog/posts/react-memo-is-good-actually/
Тимоти Пиллард в своем блоге собрал список наиболее популярных заблуждений о мемоизации в React и объяснил, почему он с этим не согласен. Речь идет о React.memo, React.useMemo, React.useCallback. Кратко о чем он написал:
- «React в любом случае настолько быстр, что React.memo не нужен». В большинстве кейсов React действительно быстрый. API мемоизации существует, чтобы заполнить пробел в модели рендеринга React.
Производительность приложения зависит от множества факторов, а проблемы производительности React приложения в большинстве случаев можно решить с помощью сочетания архитектурных паттернов, рефакторинга и разных инструментов, включая React.memo.
- «React.memo контрпродуктивен». React.memo может быть контрпродуктивным, если им неправильно пользоваться, например, если компонент постоянно получает разные пропсы, то это сделает мемоизацию неэффективной, т.к. повлечет за собой ненужные сравнения.
- «React.memo не работает с пропсом children». Эта проблема происходит из-за того, что React создает элемент через вызов React.createElement(…), который постоянно возвращает новый объект. Этого не произойдет, если передавать в children переменную с элементом, объявленную вне функции компонента, пример:
const someUIElement = <SomeUIComponent />;
function App() {
return <MemoizedComponent>{someUIElement}</MemoizedComponent>;
}
https://timtech.blog/posts/react-memo-is-good-actually/
Tim's Tech Blog
React memo is good actually
React memo, useMemo & useCallback can be controversial. Let us review the most common misconceptions about them, and see how they're good, actually.
👍22👎1
Media is too big
VIEW IN TELEGRAM
react-magic-motion – простая анимация для ваших компонентов
react-magic-motion позволяет автоматически добавить в приложение простую анимацию для элементов. Можно использовать для создания анимации появления/исчезновения элементов в списке, открытия карточки, переключения табов. Библиотека сделана на основе Framer Motion.
https://www.react-magic-motion.com/
react-magic-motion позволяет автоматически добавить в приложение простую анимацию для элементов. Можно использовать для создания анимации появления/исчезновения элементов в списке, открытия карточки, переключения табов. Библиотека сделана на основе Framer Motion.
https://www.react-magic-motion.com/
👍13🔥7
Как и почему Daily Dev перешла с Preact на React
В Daily Dev рассказали, как мигрировали с Preact на React. Изначально они начали проект с Preact и использовали его с Next.js для SSR. Preact был выбран из-за его размера и совместимости с Next.js.
С этим стеком приложение в продакшене работало хорошо, но при локальной разработке были проблемы, связанные с горячей перезагрузкой модулей, обработкой ошибок и медленным рендерингом. Последнее было наиболее критичным, потому что Preact в режиме разработки работал гораздо медленнее, чем ожидали.
Были попытки исправить проблемы в текущем стеке, но это не особо повлияло на результат. Например, если отключить плагин совместимости Preact для Next.js, то улучшится производительность приложения, но перестанет работать горячая перезагрузка модулей.
Единственным вариантом решения проблемы стала замена Preact на React. Т.к. в проекте было много адаптеров Preact для работы с Next.js, то переезд на React не был долгим. Также команда Daily Dev замерила размер бандла – для главной страницы с использованием React он был всего на 34КБ больше.
https://daily.dev/blog/moving-back-to-react
В Daily Dev рассказали, как мигрировали с Preact на React. Изначально они начали проект с Preact и использовали его с Next.js для SSR. Preact был выбран из-за его размера и совместимости с Next.js.
С этим стеком приложение в продакшене работало хорошо, но при локальной разработке были проблемы, связанные с горячей перезагрузкой модулей, обработкой ошибок и медленным рендерингом. Последнее было наиболее критичным, потому что Preact в режиме разработки работал гораздо медленнее, чем ожидали.
Были попытки исправить проблемы в текущем стеке, но это не особо повлияло на результат. Например, если отключить плагин совместимости Preact для Next.js, то улучшится производительность приложения, но перестанет работать горячая перезагрузка модулей.
Единственным вариантом решения проблемы стала замена Preact на React. Т.к. в проекте было много адаптеров Preact для работы с Next.js, то переезд на React не был долгим. Также команда Daily Dev замерила размер бандла – для главной страницы с использованием React он был всего на 34КБ больше.
https://daily.dev/blog/moving-back-to-react
daily.dev
Moving back to React
Discover the story behind daily.dev's transition from Preact to React for frontend development. This post explores the challenges, solutions, and benefits of migrating to React, enhancing our web app's performance and development experience.
👍9
Новый хук useOptimistic
В React Canary появился хук useOptimistic. Он позволяет показывать другой стейт, пока выполняется асинхронная функция. Пример:
Разберем как работает этот хук:
optimisticState - это оптимистическое состояние, по умолчанию оно соотвествует state.
addOptimistic - это функция диспатчер, которая принимает optimisticValue и будет вызывать updateFn.
state - это источник правды, если state был изменен, то optimisticState будет установлен в state.
updateFn - это функция мутации, которая принимает текущее состояние и значение optimisticValue и возвращает новое состояние optimisticState.
Чтобы на UI пометить текущий стейт как оптимистичный, можно в updateFn возвращать новый объект с полем sending: true и при рендере показывать сообщение об отправке при наличии sending. Пример:
https://react.dev/reference/react/useOptimistic
В React Canary появился хук useOptimistic. Он позволяет показывать другой стейт, пока выполняется асинхронная функция. Пример:
function AppContainer() {
const [optimisticState, addOptimistic] = useOptimistic(
state,
// updateFn
(currentState, optimisticValue) => {
// merge and return new state
// with optimistic value
}
);
}
Разберем как работает этот хук:
optimisticState - это оптимистическое состояние, по умолчанию оно соотвествует state.
addOptimistic - это функция диспатчер, которая принимает optimisticValue и будет вызывать updateFn.
state - это источник правды, если state был изменен, то optimisticState будет установлен в state.
updateFn - это функция мутации, которая принимает текущее состояние и значение optimisticValue и возвращает новое состояние optimisticState.
Чтобы на UI пометить текущий стейт как оптимистичный, можно в updateFn возвращать новый объект с полем sending: true и при рендере показывать сообщение об отправке при наличии sending. Пример:
function Thread({ messages, sendMessage }) {
const formRef = useRef();
async function formAction(formData) {
addOptimisticMessage(formData.get("message"));
formRef.current.reset();
await sendMessage(formData);
}
const [optimisticMessages, addOptimisticMessage] = useOptimistic(
messages,
(state, newMessage) => [
...state,
{
text: newMessage,
sending: true
}
]
);
return (
<>
{optimisticMessages.map((message, index) => (
<div key={index}>
{message.text}
{!!message.sending && <small> (Sending...)</small>}
</div>
))}
<form action={formAction} ref={formRef}>
<input type="text" name="message" placeholder="Hello!" />
<button type="submit">Send</button>
</form>
</>
);
}
https://react.dev/reference/react/useOptimistic
react.dev
useOptimistic – React
The library for web and native user interfaces
🔥12👍7