Skip to content

useAtoms.ts ​

Назначение файла ​

Модуль предоставляет хук useAtoms(), который читает несколько атомов как один объект и возвращает их распакованные значения.

Общая информация ​

useAtoms() полезен для компонентов и представлений, которые работают с несколькими состояниями одновременно, например с viewModel.state. Вместо отдельного вызова useAtom() для каждого поля хук принимает объект атомов и возвращает объект значений той же формы.

Объект атомов можно создавать прямо в рендере, например useAtoms({ s1, s2 }). Хук сохраняет предыдущий объект, пока его ключи и атомы совпадают, поэтому производное значение остается ссылочно стабильным, а подписка не пересоздается.

Концептуальная архитектура ​

Внутренне модуль:

  1. Нормализует undefined к пустому объекту.
  2. Сохраняет предыдущий объект атомов, пока следующий имеет те же ключи и те же атомы; сравнение выполняется через objectEquals.
  3. Создает вычисляемый атом через compute(), который читает каждое поле из переданного объекта атомов.
  4. Использует objectEquals как стратегию сравнения, чтобы не отдавать новый объект без фактического изменения значений.
  5. Делегирует подписку и управление жизненным циклом в 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>;
}