useAtoms.ts
Назначение файла
Модуль предоставляет хук useAtoms(), который читает несколько атомов как один объект и возвращает их распакованные значения.
Общая информация
useAtoms() полезен для компонентов и представлений, которые работают с несколькими состояниями одновременно, например с viewModel.state. Вместо отдельного вызова useAtom() для каждого поля хук принимает объект атомов и возвращает объект значений той же формы.
Объект атомов можно создавать прямо в рендере, например useAtoms({ s1, s2 }). Хук сохраняет предыдущий объект, пока его ключи и атомы совпадают, поэтому производное значение остается ссылочно стабильным, а подписка не пересоздается.
Концептуальная архитектура
Внутренне модуль:
- Нормализует
undefinedк пустому объекту. - Сохраняет предыдущий объект атомов, пока следующий имеет те же ключи и те же атомы; сравнение выполняется через
objectEquals. - Создает вычисляемый атом через
compute(), который читает каждое поле из переданного объекта атомов. - Использует
objectEqualsкак стратегию сравнения, чтобы не отдавать новый объект без фактического изменения значений. - Делегирует подписку и управление жизненным циклом в
useAtom(), который построен наuseSyncExternalStore()и доставляет обновления синхронно.
Такой подход сохраняет единый источник реактивности и уменьшает количество ручного кода в React-компонентах.
Описание публичного API
useAtoms(): Record<string, never>
- При вызове без аргументов возвращает пустой объект.
useAtoms<TSourceAtoms>(sources: TSourceAtoms): TResult
sources: объект, где каждое поле являетсяAtom<unknown>. Объект можно создавать прямо в рендере.- Возвращает объект той же структуры, но вместо атомов содержит их текущие значения. Результат сохраняет идентичность, пока значения не меняются.
- Перерендеривает компонент один раз, когда меняется хотя бы одно из наблюдаемых значений, а значения нового набора источников показывает в том же коммите.
Примеры использования
tsx
import React from 'react';
import { atom } from '@nrgyjs/core';
import { useAtoms } from '@nrgyjs/react';
const firstName = atom('Ada');
const lastName = atom('Lovelace');
export function UserCard() {
const { firstName: first, lastName: last } = useAtoms({
firstName,
lastName,
});
return <span>{first} {last}</span>;
}