Использование хука useSyncExternalStore
В React 18 появился новый хук useSyncExternalStore, который используется для чтения и подписки на внешние источники данных и совместим с конкурентным рендерингом. В основном он используется в библиотеках управления состояния, например, Redux для реализации селекторов. Также хук useSyncExternalStore может использоваться и в коде приложения для предотвращения лишних ререндеров компонента.
Для примера рассмотрим хук useLocation из библиотеки react-router. Он возвращает объект с несколькими атрибутами.
Возможно для работы компонента не нужны все атрибуты, однако при изменении любого из них произойдет ререндер компонента, даже если он не используется. Это может негативно повлиять на производительность приложения, особенно если этот хук используется в главном компоненте приложения App.js.
Для того чтобы избежать лишних ререндеров в данном примере, можно получать нужный атрибут через селектор, используя useSyncExternalStore. Хук принимает 3 аргумента:
- subscribe: функция, которая вызывает колбек при изменении значений.
- getSnapshot: функция, которая возвращает текущее значение стора.
- getServerSnapshot: функция, которая возвращает значение стора во время серверного рендеринга.
Чтобы реализовать через useSyncExternalStore селектор location, необходимо установить библиотеку history. Перенесем API history на аргументы useSyncExternalStore:
- history.listen: подписки на изменения.
- history: текущее значение.
Таким образом, реализация кастомного хука будет довольна проста:
В React 18 появился новый хук useSyncExternalStore, который используется для чтения и подписки на внешние источники данных и совместим с конкурентным рендерингом. В основном он используется в библиотеках управления состояния, например, Redux для реализации селекторов. Также хук useSyncExternalStore может использоваться и в коде приложения для предотвращения лишних ререндеров компонента.
Для примера рассмотрим хук useLocation из библиотеки react-router. Он возвращает объект с несколькими атрибутами.
function CurrentHash() {
const { hash } = useLocation();
return <div>{hash}</div>;
}
Возможно для работы компонента не нужны все атрибуты, однако при изменении любого из них произойдет ререндер компонента, даже если он не используется. Это может негативно повлиять на производительность приложения, особенно если этот хук используется в главном компоненте приложения App.js.
Для того чтобы избежать лишних ререндеров в данном примере, можно получать нужный атрибут через селектор, используя useSyncExternalStore. Хук принимает 3 аргумента:
- subscribe: функция, которая вызывает колбек при изменении значений.
- getSnapshot: функция, которая возвращает текущее значение стора.
- getServerSnapshot: функция, которая возвращает значение стора во время серверного рендеринга.
Чтобы реализовать через useSyncExternalStore селектор location, необходимо установить библиотеку history. Перенесем API history на аргументы useSyncExternalStore:
- history.listen: подписки на изменения.
- history: текущее значение.
Таким образом, реализация кастомного хука будет довольна проста:
function useHistorySelector(selector) {
return useSyncExternalStore(history.listen, () =>
selector(history)
);
}
function CurrentPathname() {
const pathname = useHistorySelector(
(history) => history.location.pathname
);
return <div>{pathname}</div>;
}
function CurrentHash() {
const hash = useHistorySelector(
(history) => history.location.hash
);
return <div>{hash}</div>;
}
legacy.reactjs.org
Hooks API Reference – React
A JavaScript library for building user interfaces
👍13🔥2
React и композиция функций
При создании приложения на React бывает необходимо делать сразу несколько вещей на каждой странице:
- проверять статус аутентификации пользователя;
- проверять фича-тоглы для отображения фич;
- логирование работы компонента;
- рендер лэйаута (навигация, боковое меню и т.д.)
Подобные вещи называют сквозными проблемами. Если страниц много, то на каждую страницу приходится копировать одинаковый код для решения подобных сквозных проблем.
Чтобы избавиться от дублирования кода, можно реализовать проверки и рендер в отдельных компонентах и вложить их в друг друга:
Недостаток такого подхода в том, что если изменится список сквозных проблем, то нужно обновить код всех страниц, где используются данные вложенные компоненты.
Более оптимальный вариант решения проблемы – использовать HOC. Это функция, которая принимает компонент и возвращает новый компонент. Новый компонент рендерит оригинальный компонент, но с дополнительной логикой.
Для каждой сквозной проблемы можно создать отдельный HOC и, используя функциональную композицию, объединить их все в один HOC:
Теперь решения сквозных проблем собраны и изменяются в одном месте. Для использования в компоненте нужно импортировать HOC withProviders:
https://medium.com/javanoscript-scene/why-every-react-developer-should-learn-function-composition-23f41d4db3b1
При создании приложения на React бывает необходимо делать сразу несколько вещей на каждой странице:
- проверять статус аутентификации пользователя;
- проверять фича-тоглы для отображения фич;
- логирование работы компонента;
- рендер лэйаута (навигация, боковое меню и т.д.)
Подобные вещи называют сквозными проблемами. Если страниц много, то на каждую страницу приходится копировать одинаковый код для решения подобных сквозных проблем.
Чтобы избавиться от дублирования кода, можно реализовать проверки и рендер в отдельных компонентах и вложить их в друг друга:
const MyPage = ({ user = {}, signIn, features = [], log }) => {
return (
<>
<AuthStatusProvider>
<FeatureProvider>
<LogProvider>
<StandardLayout>
<div className="content">{/* our actual page content... */}</div>
</StandardLayout>
</LogProvider>
</FeatureProvider>
</AuthStatusProvider>
</>
);
};
Недостаток такого подхода в том, что если изменится список сквозных проблем, то нужно обновить код всех страниц, где используются данные вложенные компоненты.
Более оптимальный вариант решения проблемы – использовать HOC. Это функция, которая принимает компонент и возвращает новый компонент. Новый компонент рендерит оригинальный компонент, но с дополнительной логикой.
Для каждой сквозной проблемы можно создать отдельный HOC и, используя функциональную композицию, объединить их все в один HOC:
const compose = (...fns) => (x) => fns.reduceRight((y, f) => f(y), x);
const withProviders = compose(
withUser,
withFeatures,
withLogger,
withLayout
);
export default withProviders;
Теперь решения сквозных проблем собраны и изменяются в одном месте. Для использования в компоненте нужно импортировать HOC withProviders:
const MyPage = ({ user = {}, signIn, features = [], log }) => {
return <>{/* our actual page content... */}</>;
};
const MyPageWithProviders = withProviders(MyPage);
https://medium.com/javanoscript-scene/why-every-react-developer-should-learn-function-composition-23f41d4db3b1
Medium
Why Every React Developer Should Learn Function Composition
Imagine you’re building a React application. There are a number of things you want to do on just about every page view of the application.
👍9
Обработка ошибок в React
В приложении могут возникать самые разные ошибки: от ошибки сети до неправильной работы хука в сторонней библиотеке. Если ваше приложение не будет обрабатывать такие ошибки, то оно может сломаться, отображая пользователю белый экран. В React для обработки ошибок используется Error Boundaries – механизм, когда ошибка в дереве компонентов всплывает до компонента обработчика ошибки и как-то обрабатывает его, например, отображая компонент-заглушку. Компонент обработки ошибок становится Error Boundaries, если он классовый и реализованы методы
У Error Boundaries есть недостаток, он не обрабатывает ошибки, которые возникли в следующих случаях:
- обработка событий;
- асинхронный код (setTimeout или requestAnimationFrame);
- во время SSR;
- возникли в Error Boundaries;
Также нет механизма повторного рендера дочернего компонента у Error Boundaries для восстановления приложения.
Чтобы обойти эти ограничения, можно использовать библиотеку react-error-boundary. Ее преимущество в том, что она позволяет восстановить работу приложения после ошибки. Также есть хук для обработки ошибок в асинхронном коде. Пример работы библиотеки:
https://github.com/bvaughn/react-error-boundary
В приложении могут возникать самые разные ошибки: от ошибки сети до неправильной работы хука в сторонней библиотеке. Если ваше приложение не будет обрабатывать такие ошибки, то оно может сломаться, отображая пользователю белый экран. В React для обработки ошибок используется Error Boundaries – механизм, когда ошибка в дереве компонентов всплывает до компонента обработчика ошибки и как-то обрабатывает его, например, отображая компонент-заглушку. Компонент обработки ошибок становится Error Boundaries, если он классовый и реализованы методы
static getDerivedStateFromError или componentDidCatch.У Error Boundaries есть недостаток, он не обрабатывает ошибки, которые возникли в следующих случаях:
- обработка событий;
- асинхронный код (setTimeout или requestAnimationFrame);
- во время SSR;
- возникли в Error Boundaries;
Также нет механизма повторного рендера дочернего компонента у Error Boundaries для восстановления приложения.
Чтобы обойти эти ограничения, можно использовать библиотеку react-error-boundary. Ее преимущество в том, что она позволяет восстановить работу приложения после ошибки. Также есть хук для обработки ошибок в асинхронном коде. Пример работы библиотеки:
import {ErrorBoundary} from 'react-error-boundary'
function ErrorFallback({error, resetErrorBoundary}) {
return (
<div role="alert">
<pre>{error.message}</pre>
<button onClick={resetErrorBoundary}>Try again</button>
</div>
)
}
const ui = (
<ErrorBoundary
FallbackComponent={ErrorFallback}
onReset={() => {
// reset the state of your app so the error doesn't happen again
}}
>
<ComponentThatMayError />
</ErrorBoundary>
)
https://github.com/bvaughn/react-error-boundary
GitHub
GitHub - bvaughn/react-error-boundary: Simple reusable React error boundary component
Simple reusable React error boundary component. Contribute to bvaughn/react-error-boundary development by creating an account on GitHub.
👍15🔥2
Под капотом у Mobx. Пишем свою реактивную библиотеку с нуля
Когда начинаете использовать Mobx, то кажется, что внутри него используется какая-то магия. Но если посмотреть исходники, то окажется, что все написано на JS и используются стандартные объекты.
При создании Observable объекта и вывода его в консоль можно увидеть, что Observable оборачивает значение в Proxy. Внутри Proxy объекта находятся реакции, а внутри реакций находятся наблюдаемые значения и получается рекурсивная зависимость.
Григорий Гаврилов в статье на Хабре объяснил, как работает Mobx под капотом, реализовав основное API библиотеки.
https://habr.com/ru/post/689374/
Когда начинаете использовать Mobx, то кажется, что внутри него используется какая-то магия. Но если посмотреть исходники, то окажется, что все написано на JS и используются стандартные объекты.
При создании Observable объекта и вывода его в консоль можно увидеть, что Observable оборачивает значение в Proxy. Внутри Proxy объекта находятся реакции, а внутри реакций находятся наблюдаемые значения и получается рекурсивная зависимость.
Григорий Гаврилов в статье на Хабре объяснил, как работает Mobx под капотом, реализовав основное API библиотеки.
https://habr.com/ru/post/689374/
Хабр
Под капотом у Mobx. Пишем свою реактивную библиотеку с нуля
Первое мое знакомство с Mobx началось с удивления. Я не понимал всю магию библиотеки и задавал себе вопрос: “А как это возможно?”. Кажется, в ней используются какие-то подкапотные возможности JS или...
👍10
Будущее рендеринга в React
В текущий момент есть два подхода для рендеринга приложений на React:
- Client-Side Rendering. Сервер отдает базовый HTML и JS бандл и уже в браузере происходит рендеринг и получение данных по API.
- Server-side rendering. Получение данных и рендеринг приложения происходит на стороне сервера с помощью renderToString, который возвращает HTML для передачи клиенту. После получения HTML и JS на клиенте происходит гидратация.
У обоих из этих подходов есть свои плюсы и минусы в терминах Web Vitals, о которых пишет автор статьи. Новые подходы к рендеру приложения на React предназначены для решения основных минусов текущих подходов.
Streaming SSR. Новое API renderToPipeableStream позволяет в связке с Suspense разделить приложение на сегменты, каждый из которых будет рендериться независимо от остальных. При успешном рендере сегмента, HTML будет передаваться на клиент и вставляться в свое место в DOM.
Server components. Позволяет полностью рендерить компоненты приложения на сервере и не требует гидратации на клиенте. Так как компоненты рендерятся только на сервере, то имеют полный доступ к бэкенду и могут обращаться к БД. Один из вариантов использования такого подхода – тяжелые для рендера компоненты, которые будут быстрее рендериться на сервере, чем в браузере пользователя.
Server components еще находятся в альфа версии и недоступны для использования. Streaming SSR также еще официально не зарелизина. Команда React планирует, что разработчики не будут напрямую использовать новые подходы в своих проектах, т.к. они будут сложными в интеграции. Вместо этого, новые подходы рендера должны появиться в фреймворках, которые предоставят более простой интерфейс для работы. Например, новая версия Next.js Layouts RFC должна будет поддержать новые подходы рендера React.
https://prateeksurana.me/blog/future-of-rendering-in-react/
В текущий момент есть два подхода для рендеринга приложений на React:
- Client-Side Rendering. Сервер отдает базовый HTML и JS бандл и уже в браузере происходит рендеринг и получение данных по API.
- Server-side rendering. Получение данных и рендеринг приложения происходит на стороне сервера с помощью renderToString, который возвращает HTML для передачи клиенту. После получения HTML и JS на клиенте происходит гидратация.
У обоих из этих подходов есть свои плюсы и минусы в терминах Web Vitals, о которых пишет автор статьи. Новые подходы к рендеру приложения на React предназначены для решения основных минусов текущих подходов.
Streaming SSR. Новое API renderToPipeableStream позволяет в связке с Suspense разделить приложение на сегменты, каждый из которых будет рендериться независимо от остальных. При успешном рендере сегмента, HTML будет передаваться на клиент и вставляться в свое место в DOM.
Server components. Позволяет полностью рендерить компоненты приложения на сервере и не требует гидратации на клиенте. Так как компоненты рендерятся только на сервере, то имеют полный доступ к бэкенду и могут обращаться к БД. Один из вариантов использования такого подхода – тяжелые для рендера компоненты, которые будут быстрее рендериться на сервере, чем в браузере пользователя.
Server components еще находятся в альфа версии и недоступны для использования. Streaming SSR также еще официально не зарелизина. Команда React планирует, что разработчики не будут напрямую использовать новые подходы в своих проектах, т.к. они будут сложными в интеграции. Вместо этого, новые подходы рендера должны появиться в фреймворках, которые предоставят более простой интерфейс для работы. Например, новая версия Next.js Layouts RFC должна будет поддержать новые подходы рендера React.
https://prateeksurana.me/blog/future-of-rendering-in-react/
nextjs.org
Layouts RFC
Nested routes and layouts, client and server routing, React 18 features, and designed for Server Components.
👍8
Как получать данные в React
Надя Макаревич в своем блоге рассказала об оптимизации запросов на получение данных при инициализации вашего SPA приложения на React. В гайде не рассказывается о какой-то конкретной библиотеке для получения данных, а приводятся примеры паттернов получения данных и их подводные камни.
Например, можно вынести fetch за пределы компонента и тогда на момент инициализации компонента вероятнее всего данные уже будут получены. Этот способ можно использовать для наиболее критических ресурсов, которые нужно получить заранее.
https://www.developerway.com/posts/how-to-fetch-data-in-react
Надя Макаревич в своем блоге рассказала об оптимизации запросов на получение данных при инициализации вашего SPA приложения на React. В гайде не рассказывается о какой-то конкретной библиотеке для получения данных, а приводятся примеры паттернов получения данных и их подводные камни.
Например, можно вынести fetch за пределы компонента и тогда на момент инициализации компонента вероятнее всего данные уже будут получены. Этот способ можно использовать для наиболее критических ресурсов, которые нужно получить заранее.
const commentsPromise = fetch('/get-comments');
const Comments = () => {
useEffect(() => {
const dataFetch = async () => {
// just await the variable here
const data = await (await commentsPromise).json();
setState(data);
};
dataFetch();
}, [url]);
}
https://www.developerway.com/posts/how-to-fetch-data-in-react
Developerway
How to fetch data in React with performance in mind
Deep dive into data fetching in React. What is performance, fundamental libraries-agnostic patterns and techniques, how react lifecycle and browser limitations affect data fetching and apps rendering time and order.
👍6👎1
RFC: поддержка async компонентов
От Эндрю Кларка вышло RFC о поддержке асинхронных компонентов на сервере и промисов на клиенте через хук
Async/await для серверных компонентов:
Для серверных компонентов React будет ждать пока промис не зарезолвится и после чего компонент будет отрендерен, как будто значение промиса было получено сразу же. Т.е. не будет рендера компонента без данных.
Использование хука
Как видно из примера, хук
Это еще не финальный RFC. Остается открытым вопрос с кэшированием данных. Как обещает автор, в будущем будет предложен отдельный RFC по кэшированию, а релизится API запросов будет вместе с API кэширования.
RFC https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md
Обсуждение https://github.com/reactjs/rfcs/pull/229
От Эндрю Кларка вышло RFC о поддержке асинхронных компонентов на сервере и промисов на клиенте через хук
use. Эти два больших нововведения могут существенно облегчить работу с API и базами данных в React. Компоненты, которые используют эти возможности, должны будут обернуты в Suspense.Async/await для серверных компонентов:
async function Note({id}) {
const note = await db.posts.get(id);
return (
<div>
<h1>{note.noscript}</h1>
</div>
);
}
Для серверных компонентов React будет ждать пока промис не зарезолвится и после чего компонент будет отрендерен, как будто значение промиса было получено сразу же. Т.е. не будет рендера компонента без данных.
Использование хука
use для браузерных компонентов:
function Note({id, shouldIncludeAuthor}) {
const note = use(fetchNote(id));
let byline = null;
if (shouldIncludeAuthor) {
const author = use(fetchNoteAuthor(note.authorId));
byline = <h2>{author.displayName}</h2>;
}
return (
<div>
<h1>{note.noscript}</h1>
{byline}
</div>
);
}
Как видно из примера, хук
use, в отличие от других хуков, можно вызывать внутри условий, также его можно вызывать внутри циклов. Браузерные компоненты не должны быть определены как async. Чтобы получить данные из промиса, достаточно использовать только хук use. Это еще не финальный RFC. Остается открытым вопрос с кэшированием данных. Как обещает автор, в будущем будет предложен отдельный RFC по кэшированию, а релизится API запросов будет вместе с API кэширования.
RFC https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md
Обсуждение https://github.com/reactjs/rfcs/pull/229
GitHub
rfcs/text/0000-first-class-support-for-promises.md at first-class-promises · acdlite/rfcs
RFCs for changes to React. Contribute to acdlite/rfcs development by creating an account on GitHub.
🔥10
Tremor – библиотека для создания дашбордов
Новая библиотека компонентов, которая подойдет для проектов-дашбордов. Она включает в себя разные виды графиков, основные UI компоненты, а также компоненты для создания шаблона – колонки и блоки.
Под капотом используется Tailwind CSS, и есть возможность изменения цвета компонента. Также на сайте уже есть примеры работы библиотеки с готовыми блоками.
https://www.tremor.so/
Новая библиотека компонентов, которая подойдет для проектов-дашбордов. Она включает в себя разные виды графиков, основные UI компоненты, а также компоненты для создания шаблона – колонки и блоки.
Под капотом используется Tailwind CSS, и есть возможность изменения цвета компонента. Также на сайте уже есть примеры работы библиотеки с готовыми блоками.
https://www.tremor.so/
Tremor – Copy-and-Paste Tailwind CSS UI Components for Charts and Dashboards
Open-source, accessible React UI components styled with Tailwind CSS to build charts and dashboards.
👍4
React, я люблю тебя, но ты сводишь меня с ума
На хабре вышел перевод статьи Франсуа Занинотто с критикой React.
Автор подсвечивает несколько проблем, которые возникают при разработке React приложений:
- Работа с формами. Для ручного получения данных с формы есть управляемые и неуправляемые инпуты. Чтобы обработать поле инпута, нужно создать отдельный стейт и функцию обработчик. Если захотите использовать библиотеку для работы с формами, то будьте готовы, что в них тоже есть недостатки: некоторые из них уже не поддерживаются, а другие медленно работают или в них слишком запутанная документация.
- Контекст. В useContext отсуствует критически важная вещь – возможность реагировать на изменение только определенных полей объекта, как в Redux useSelector. Это приводит к тому, что приходится разделять контекст на более мелкие части.
- useEffect и useCallback. Требует ручного управления зависимостями, заставляя записывать все используемые переменные в список зависимостей. В Solid.js таких проблем нет.
- Строгость хуков. Хуки нельзя вызывать условно. Хоть и известно, что если компонент с хуком нужно показывать по условию, то его нужно вкладывать в промежуточный компонент для предотвращения рендеринга, но все равно, непонятно зачем это нужно делать. Это просто один из примеров сложности хуков.
- Старость фреймворка. React появился в 2013 году и сейчас, при поиске нужной библиотеки для проекта, можно заметить популярные npm пакеты, которые редко обновляются. В основном в них используются классовые компоненты, из-за чего они не очень привлекательны для новых контрибьюторов.
https://habr.com/ru/company/timeweb/blog/693072/
На хабре вышел перевод статьи Франсуа Занинотто с критикой React.
Автор подсвечивает несколько проблем, которые возникают при разработке React приложений:
- Работа с формами. Для ручного получения данных с формы есть управляемые и неуправляемые инпуты. Чтобы обработать поле инпута, нужно создать отдельный стейт и функцию обработчик. Если захотите использовать библиотеку для работы с формами, то будьте готовы, что в них тоже есть недостатки: некоторые из них уже не поддерживаются, а другие медленно работают или в них слишком запутанная документация.
- Контекст. В useContext отсуствует критически важная вещь – возможность реагировать на изменение только определенных полей объекта, как в Redux useSelector. Это приводит к тому, что приходится разделять контекст на более мелкие части.
- useEffect и useCallback. Требует ручного управления зависимостями, заставляя записывать все используемые переменные в список зависимостей. В Solid.js таких проблем нет.
- Строгость хуков. Хуки нельзя вызывать условно. Хоть и известно, что если компонент с хуком нужно показывать по условию, то его нужно вкладывать в промежуточный компонент для предотвращения рендеринга, но все равно, непонятно зачем это нужно делать. Это просто один из примеров сложности хуков.
- Старость фреймворка. React появился в 2013 году и сейчас, при поиске нужной библиотеки для проекта, можно заметить популярные npm пакеты, которые редко обновляются. В основном в них используются классовые компоненты, из-за чего они не очень привлекательны для новых контрибьюторов.
https://habr.com/ru/company/timeweb/blog/693072/
Хабр
React, я люблю тебя, но ты сводишь меня с ума
Привет, друзья! Представляю вашему вниманию перевод этой статьи , вызывавшей определенный резонанс в сообществе React-разработчиков . Дорогой React , мы встречаемся уже почти 10 лет. Мы прошли долгий...
👍8👎5
Полностью типизированные веб-приложения
Кент С. Доддс рассказывает о сквозном покрытии типов в веб-приложениях, от БД до UI через разные границы: localStorage, сеть, БД.
Например, при получении данных из localStorage нельзя точно определить, какие будут получены данные, т.к. со временем они могут измениться. Если кастовать тип для данных из localStorage, то может возникнуть runtime ошибка, например, из-за того, что нет нужного поля в объекте.
Кент С. Доддс рекомендует валидировать данные после получения их из какого-либо внешнего источника. Один из вариантов – библиотека zod, которая позволяет описать схему данных и получить ее тип. Если окажется, что объект не совпадает со схемой, то будет выкинута ошибка. В ином случае вы будете уверены, что работаете с правильными данными.
https://www.epicweb.dev/fully-typed-web-apps
Кент С. Доддс рассказывает о сквозном покрытии типов в веб-приложениях, от БД до UI через разные границы: localStorage, сеть, БД.
Например, при получении данных из localStorage нельзя точно определить, какие будут получены данные, т.к. со временем они могут измениться. Если кастовать тип для данных из localStorage, то может возникнуть runtime ошибка, например, из-за того, что нет нужного поля в объекте.
Кент С. Доддс рекомендует валидировать данные после получения их из какого-либо внешнего источника. Один из вариантов – библиотека zod, которая позволяет описать схему данных и получить ее тип. Если окажется, что объект не совпадает со схемой, то будет выкинута ошибка. В ином случае вы будете уверены, что работаете с правильными данными.
import { z } from "zod"
const Ticket = z.object({
workshopId: z.string(),
attendeeId: z.string(),
discountCode: z.string().optional()
})
type Ticket = z.infer<typeof Ticket>
const rawTicket = JSON.parse(localStorage.get('ticket'))
const result = Ticket.safeParse(rawTicket);
if (result.success) {
const ticket = result.data
// ^? Ticket
} else {
// result.error will have a handy informative error
}
https://www.epicweb.dev/fully-typed-web-apps
Epic Web Dev
Fully Typed Web Apps
The main thing that makes end-to-end type safety difficult is simple: boundaries. The secret to fully typed web apps is typing the boundaries.
🔥10
Next.js Conf
На этой неделе прошла конференция Next.js Conf, на которой представили Next.js 13 и Turbopack – бандлер и сборщик приложения, написанный на Rust.
В Next.js 13 добавили новую папку для роутинга –
Layouts.
Позволяет использовать шаблоны для нескольких компонентов. Реализуется через создание файла layout.js.
Server Components.
Next.js начал поддерживать серверные компоненты. Согласно документации все компоненты внутри директории
Streaming.
Возможность прогрессивного рендера компонентов на странице.
Поддержка async компонентов.
Означает поддержку недавнего RFC о загрузке данных.
Также на конференции рассказали про новый бандлер и сборщик приложения Turbopack. Написан он на Rust, а его главный разработчик – Тобиас Копперс, создатель Webpack. По информации от авторов, Turbopack в 700 раз быстрее Webpack и как минимум в 10 раз быстрее чем Vite. Пока что бандлер находится в альфа-версии.
https://nextjs.org/blog/next-13
На этой неделе прошла конференция Next.js Conf, на которой представили Next.js 13 и Turbopack – бандлер и сборщик приложения, написанный на Rust.
В Next.js 13 добавили новую папку для роутинга –
/app. В ней можно использовать новые фичи, о которых давно говорили в React. Layouts.
Позволяет использовать шаблоны для нескольких компонентов. Реализуется через создание файла layout.js.
Server Components.
Next.js начал поддерживать серверные компоненты. Согласно документации все компоненты внутри директории
/app являются серверными компонентами по умолчанию. Чтобы обозначить, что компонент является клиентским, нужно в начале файла объявить директиву 'use client';.Streaming.
Возможность прогрессивного рендера компонентов на странице.
Поддержка async компонентов.
Означает поддержку недавнего RFC о загрузке данных.
Также на конференции рассказали про новый бандлер и сборщик приложения Turbopack. Написан он на Rust, а его главный разработчик – Тобиас Копперс, создатель Webpack. По информации от авторов, Turbopack в 700 раз быстрее Webpack и как минимум в 10 раз быстрее чем Vite. Пока что бандлер находится в альфа-версии.
https://nextjs.org/blog/next-13
nextjs.org
Next.js 13
Next.js 13 introduces layouts, React Server Components, and streaming in the app directory, as well as Turbopack, an improved image component, and the brand new font component.
🔥5
Пишем свою библиотеку управления состоянием
Джуд Хантер в своем блоге рассказал, как самостоятельно реализовать библиотеку для управления состоянием наподобие Zustand.
Одним из преимуществ библиотек для управления состоянием, в отличие от контекста, является то, что изменение стора не вызывает ререндера всего дерева компонентов. Реализовано это за счет использования селекторов в компоненте.
Чтобы показать свою работу, Джуд Хантер создал функцию создания стора и хук для подписки за изменениями. По аналогии с Zustand при создании стора передаются экшены для изменения стора. Код реализации хука селектора:
https://judehunter.dev/blog/how-to-write-your-own-state-management-library
Джуд Хантер в своем блоге рассказал, как самостоятельно реализовать библиотеку для управления состоянием наподобие Zustand.
Одним из преимуществ библиотек для управления состоянием, в отличие от контекста, является то, что изменение стора не вызывает ререндера всего дерева компонентов. Реализовано это за счет использования селекторов в компоненте.
Чтобы показать свою работу, Джуд Хантер создал функцию создания стора и хук для подписки за изменениями. По аналогии с Zustand при создании стора передаются экшены для изменения стора. Код реализации хука селектора:
const useSelector = <STATE,>(
store: {state: STATE; subscribe: any},
selector: (state: STATE) => any,
) => {
const [selectedValue, setSelectedValue]
= useState(selector(store.state))
useEffect(() => {
return store.subscribe(newState => {
setSelectedValue(
selector(newState);
);
});
}, []);
return selectedValue;
}
https://judehunter.dev/blog/how-to-write-your-own-state-management-library
judehunter.dev
How to write your own state management library · Jude Hunter
Ever wondered what magic happens behind the scenes of state management libraries for SPA frameworks? Jump in for a deep dive on selectors, subscribers, preventing re-renders, and more.
👍4🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
Интерактивный WebGL в Next.js
Для лендинга конференции Next.js Conf разработчики из Next.js сделали интерактивную фигуру на WebGL и рассказали в своем блоге о процессе создания.
Для реализации WebGL использовали библиотеки react-three-fiber и drei – утилитарная библиотека для react-three-fiber, в которой собраны основные паттерны. Для постпроцессинга используется библиотека
https://vercel.com/blog/building-an-interactive-webgl-experience-in-next-js
Для лендинга конференции Next.js Conf разработчики из Next.js сделали интерактивную фигуру на WebGL и рассказали в своем блоге о процессе создания.
Для реализации WebGL использовали библиотеки react-three-fiber и drei – утилитарная библиотека для react-three-fiber, в которой собраны основные паттерны. Для постпроцессинга используется библиотека
@react-three/postprocessing. https://vercel.com/blog/building-an-interactive-webgl-experience-in-next-js
👍2
Конференция для JavaScript-разработчиков HolyJS 2022 Autumn
🌐 10–11 ноября — онлайн
👥 20 ноября — офлайн в Москве
(с возможностью удаленного участия для тех, кто не готов добраться)
Программа конференции полностью готова.
Из интересного про React:
✔ Сергей Константинов, воркшоп «Пишем игру на React и разбираемся с react-reconciler»
✔ Дмитрий Грош, доклад «Батчинг в React»
✔ Константин Астапов, доклад «How to build large react-redux application without code mess»
✔Сэм Булатов, доклад «Введение в реактивное программирование»
Если вам хочется на несколько часов отвлечься и побыть среди единомышленников, то приходите на HolyJS. А промокод reactnotes2022JRGpc даст скидку 20% на билеты из категории «Для частных лиц».
Подробности и билеты — holyjs.ru
🌐 10–11 ноября — онлайн
👥 20 ноября — офлайн в Москве
(с возможностью удаленного участия для тех, кто не готов добраться)
Программа конференции полностью готова.
Из интересного про React:
✔ Сергей Константинов, воркшоп «Пишем игру на React и разбираемся с react-reconciler»
✔ Дмитрий Грош, доклад «Батчинг в React»
✔ Константин Астапов, доклад «How to build large react-redux application without code mess»
✔Сэм Булатов, доклад «Введение в реактивное программирование»
Если вам хочется на несколько часов отвлечься и побыть среди единомышленников, то приходите на HolyJS. А промокод reactnotes2022JRGpc даст скидку 20% на билеты из категории «Для частных лиц».
Подробности и билеты — holyjs.ru
👍3🔥1
React Query: заполняем кэш запросов
В React Query есть поддержка загрузки данных в Suspense, для этого нужно передать параметр
Чтобы избежать подобных проблем, Доминик Дорфмайстер в своем блоге поделился способами предварительного заполнения кэша для запросов.
Во-первых, предварительно загружайте данные до рендера компонента. Если проект поддерживает SSR, то загружайте данные на сервере. Если роутер поддерживает лоадеры, то загружайте в лоадерах.
Во-вторых, если у вас данные в списке и нужен отдельный элемент из списка, то его можно получить из кэша:
Другой подход – создавать кэш для отдельного элемента после получения данных для списка:
Минус такого подхода в том, что данные могут устареть до момента, когда они понадобятся, либо эти данные могут вообще не понадобиться.
https://tkdodo.eu/blog/seeding-the-query-cache
В React Query есть поддержка загрузки данных в Suspense, для этого нужно передать параметр
suspense: true в настройки запроса. При использовании данного механизма нужно быть осторожным. Если у вас несколько запросов в одном компоненте, то возникает проблема “водопада” запросов. При рендере компонента React Query сообщает, что необходимо выполнить первый запрос, React ставит компонент на паузу и ждет выполнения. После успешного выполнения запроса, компонент перемонтируется заново и React Query сообщает, что необходимо выполнить второй запрос, и сценарий повторяется. Так возникает “водопад” запросов.Чтобы избежать подобных проблем, Доминик Дорфмайстер в своем блоге поделился способами предварительного заполнения кэша для запросов.
Во-первых, предварительно загружайте данные до рендера компонента. Если проект поддерживает SSR, то загружайте данные на сервере. Если роутер поддерживает лоадеры, то загружайте в лоадерах.
const issuesQuery = { queryKey: ['issues'], queryFn: fetchIssues }
queryClient.prefetchQuery(issuesQuery)
function Issues() {
const issues = useQuery(issuesQuery)
}
Во-вторых, если у вас данные в списке и нужен отдельный элемент из списка, то его можно получить из кэша:
const data = useQuery({
queryKey: ['todos', 'detail', id],
queryFn: () => fetchTodo(id),
initialData: () => {
return queryClient
.getQueryData(['todos', 'list'])
?.find((todo) => todo.id === id)
},
})
Другой подход – создавать кэш для отдельного элемента после получения данных для списка:
const data = useQuery({
queryKey: ['todos', 'list'],
queryFn: async () => {
const todos = await fetchTodos()
todos.forEach((todo) => {
queryClient.setQueryData(['todos', 'detail', todo.id], todo)
})
return todos
},
})
Минус такого подхода в том, что данные могут устареть до момента, когда они понадобятся, либо эти данные могут вообще не понадобиться.
https://tkdodo.eu/blog/seeding-the-query-cache
tkdodo.eu
Seeding the Query Cache
With suspense for data fetching on the horizon, it is now more important than ever to make sure your cache is seeded properly to avoid fetch waterfalls.
👍5👎1
Feature-Sliced Design: эволюция фронтенда для быстрых экспериментов
Небольшой обзор от Евгения Валяева, в котором описывается подход к разработке проекта с использованием FSD.
Если вы начинаете разработку нового проекта на React, то обратите внимание на FSD. Это гибкая архитектура проекта, в которой может работать несколько человек, разрабатывая фичи в изоляции друг от друга.
FSD – это методология, документацию которой можно посмотреть на сайте. FSD достаточно гибкий и необязательно использовать все его компоненты сразу.
https://habr.com/ru/company/inDrive/blog/693768/
Небольшой обзор от Евгения Валяева, в котором описывается подход к разработке проекта с использованием FSD.
Если вы начинаете разработку нового проекта на React, то обратите внимание на FSD. Это гибкая архитектура проекта, в которой может работать несколько человек, разрабатывая фичи в изоляции друг от друга.
FSD – это методология, документацию которой можно посмотреть на сайте. FSD достаточно гибкий и необязательно использовать все его компоненты сразу.
https://habr.com/ru/company/inDrive/blog/693768/
feature-sliced.design
Welcome | Feature-Sliced Design
Architectural methodology for frontend projects
👍20🔥7👎3
Бесплатный Community Day HolyJS 2022 Autumn — 11 ноября, онлайн
Community Day — это второй день конференции HolyJS со свободным доступом для всех желающих. Организаторы проводят его, чтобы усилия команды и Программного комитета оценило как можно больше участников.
На Community Day такая же насыщенная программа, как и в другие дни конференции. Там будут:
✔ 7️⃣ докладов с дискуссиями
✔ 2️⃣ воркшопа: улучшаем доступность маркетплейса для незрячих и пишем игру на React
✔ BoF-сессия про микрофронтенды
Бесплатная регистрация на holyjs.ru
Community Day — это второй день конференции HolyJS со свободным доступом для всех желающих. Организаторы проводят его, чтобы усилия команды и Программного комитета оценило как можно больше участников.
На Community Day такая же насыщенная программа, как и в другие дни конференции. Там будут:
✔ 7️⃣ докладов с дискуссиями
✔ 2️⃣ воркшопа: улучшаем доступность маркетплейса для незрячих и пишем игру на React
✔ BoF-сессия про микрофронтенды
Бесплатная регистрация на holyjs.ru
👍2🔥2
TanStack Router
Таннер Линсли представил новый проект – TanStack Router. Это масштабируемый роутер для приложений, написанный на TypeScript и не привязанный к конкретному фреймворку.
Автор предлагает сразу много фич из коробки:
- Управление стейтом из URL
- Встроенное кэширование
- Валидация схемы search params
- Автоматический prefetch запросов
- Лоадеры данных на уровне роута
- Code-Splitting
Для создания роутера приложения не требуется JSX, все роуты объявляются через функции. Библиотека находится в статусе беты и пока что есть адаптер только для React.
https://tanstack.com/router/v1
Таннер Линсли представил новый проект – TanStack Router. Это масштабируемый роутер для приложений, написанный на TypeScript и не привязанный к конкретному фреймворку.
Автор предлагает сразу много фич из коробки:
- Управление стейтом из URL
- Встроенное кэширование
- Валидация схемы search params
- Автоматический prefetch запросов
- Лоадеры данных на уровне роута
- Code-Splitting
Для создания роутера приложения не требуется JSX, все роуты объявляются через функции. Библиотека находится в статусе беты и пока что есть адаптер только для React.
https://tanstack.com/router/v1
Tanstack
TanStack Router
A powerful React router for client-side and full-stack react applications. Fully type-safe APIs, first-class search-params for managing state in the URL and seamless integration with the existing React ecosystem.
👍12
Forwarded from Сова пишет…
На волне очень приятных эмоций от общения на дискусии, я закончил оформлять подборку статей!
Как проектировать API, что особенного в подборе цветов для веб-сайта, как работает движок V8?
https://news.sova.dev/issues/19-1263486
Как проектировать API, что особенного в подборе цветов для веб-сайта, как работает движок V8?
https://news.sova.dev/issues/19-1263486
👍4
Монорепозиторий c Turborepo
Гайд по созданию и настройке для проекта монорепозитория со следующим стеком:
- npm для установки зависимостей и линковки пакетов;
- turborepo для оркестрации задач;
- tsc, postcss-cli и vite для сборки пакетов;
- ladle для демо-стенда;
Такой стек удобен тем, что в нем можно поменять инструмент на любой другой.
Одно из преимуществ Turborepo – кэширование результатов сборки. При автоматизированной сборке на CI кэширование может значительно увеличить скорость работы пайплайнов.
https://habr.com/ru/post/694808/
Гайд по созданию и настройке для проекта монорепозитория со следующим стеком:
- npm для установки зависимостей и линковки пакетов;
- turborepo для оркестрации задач;
- tsc, postcss-cli и vite для сборки пакетов;
- ladle для демо-стенда;
Такой стек удобен тем, что в нем можно поменять инструмент на любой другой.
Одно из преимуществ Turborepo – кэширование результатов сборки. При автоматизированной сборке на CI кэширование может значительно увеличить скорость работы пайплайнов.
https://habr.com/ru/post/694808/
Хабр
Монорепозиторий на обед
В прошлой статье я рассказывал про библиотеку компонентов и утилит handy-ones . Я задумал её не только чтобы делиться с сообществом своими наработками на постоянной основе, но главное - чтобы понять,...
👍4
Создание форм из JSON схемы
uniforms – библиотека для генерации форм на основе JSON схемы. Структура схемы и валидация может быть любой. Подключение схемы к форме происходит через адаптер. В документации uniforms рекомендуют работать с ajv, наиболее популярной библиотекой для валидации JSON схемы.
Преимущества uniforms:
- автоматическая генерация формы;
- встроенный набор компонентов для отображения любых типов полей;
- создание кастомных полей;
- асинхронная валидация формы;
- поддержка кастомных тем для стилизации;
Пример кода для генерации формы:
https://uniforms.tools/
Гайд https://www.vazco.eu/blog/a-novel-schema-first-approach-to-building-forms
uniforms – библиотека для генерации форм на основе JSON схемы. Структура схемы и валидация может быть любой. Подключение схемы к форме происходит через адаптер. В документации uniforms рекомендуют работать с ajv, наиболее популярной библиотекой для валидации JSON схемы.
Преимущества uniforms:
- автоматическая генерация формы;
- встроенный набор компонентов для отображения любых типов полей;
- создание кастомных полей;
- асинхронная валидация формы;
- поддержка кастомных тем для стилизации;
Пример кода для генерации формы:
import { AutoForm } from "uniforms"
import { createBridge } from "./createBridge" // explained later
function AutomaticForm() {
return <AutoForm schema={createBridge(loginSchema)} />;
}
https://uniforms.tools/
Гайд https://www.vazco.eu/blog/a-novel-schema-first-approach-to-building-forms
uniforms.tools
Hello from uniforms | React form library for building forms from any schema | uniforms | React form library for building forms…
Denoscription will go into a meta tag in <head />
👍5👎1