useAtom.ts
Назначение файла
Модуль предоставляет React-хук useAtom(), который подписывает компонент на одно реактивное значение Atom<T>.
Общая информация
useAtom() решает базовую задачу чтения Nrgy-атома из React. Хук построен на useSyncExternalStore() из React: сам атом выступает функцией получения снимка, а синхронный эффект уведомляет React об изменениях.
Поскольку значение читается из атома в каждом рендере, смена самого атома source видна в том же коммите. Обновления атома доставляются синхронно: обновление внутри обработчика события или внутри act() рендерится без ожидания микрозадачи, а несколько обновлений в одном обработчике или внутри batch() дают один рендер.
Хук требует React 18 или новее.
Концептуальная архитектура
Хук состоит из двух частей:
subscribeмемоизируется черезuseCallback()для каждогоsource. Он создает подписку черезsyncEffect(source, onStoreChange)и возвращаетsubscription.destroyкак функцию отписки.sourceпередается вuseSyncExternalStore()и какgetSnapshot, и какgetServerSnapshot. Атомы сохраняют ссылочную стабильность значения между изменениями, поэтому React может сравнивать снимки черезObject.is.
Следствия такой конструкции:
- Атом
sourceдолжен быть стабильным между рендерами. Атом, созданный в теле рендера без мемоизации, приводит к новой подписке на каждый рендер. - Ошибка, брошенная атомом, проявляется как ошибка рендера и может быть обработана error boundary.
- Установка атома в теле рендера вызывает предупреждение React об обновлении компонента во время рендера.
Описание публичного API
useAtom<T>(source: Atom<T>): T
source: атом или вычисляемый атом, значение которого нужно читать.- Возвращает текущее значение атома типа
T. - Синхронно перерендеривает компонент при изменении значения
source.
Примеры использования
tsx
import React from 'react';
import { atom } from '@nrgyjs/core';
import { useAtom } from '@nrgyjs/react';
const counter = atom(0);
export function CounterValue() {
const value = useAtom(counter);
return <span>{value}</span>;
}