Back

Начало работы с TanStack DB для реактивных интерфейсов

Начало работы с TanStack DB для реактивных интерфейсов

Создание реактивных интерфейсов не должно требовать выбора между производительностью и простотой. Тем не менее, каждое обновление состояния в современных JavaScript-приложениях запускает каскадные ре-рендеры, сложную мемоизацию и оптимистичные обновления с большим количеством шаблонного кода. TanStack DB полностью меняет это уравнение.

Эта статья знакомит с TanStack DB — клиентским слоем базы данных, который расширяет TanStack Query коллекциями, живыми запросами и дифференциальным потоком данных для обновлений за доли миллисекунды. Вы узнаете, как он упрощает управление состоянием по сравнению с Redux или ручным кешированием, и как постепенно внедрить его в существующие проекты.

Примечание: TanStack DB в настоящее время находится в бета-версии (по состоянию на конец 2025 года). Хотя API могут эволюционировать, библиотека достаточно стабильна для изучения и постепенного внедрения в некритичных функциях.

Ключевые выводы

  • TanStack DB расширяет TanStack Query реляционными возможностями и дифференциальным потоком данных для обновления UI за доли миллисекунды
  • Коллекции оборачивают существующие запросы, обеспечивая реактивные объединения и фильтры по всему графу данных
  • Живые запросы автоматически обновляются при изменении данных без ручной инвалидации кеша или мемоизации
  • Возможно постепенное внедрение — начните с одной коллекции и мигрируйте постепенно без переписывания кода

Что такое TanStack DB?

TanStack DB — это реактивное клиентское хранилище, построенное поверх TanStack Query. В то время как TanStack Query отлично справляется с получением и кешированием серверного состояния, он рассматривает каждый результат запроса как изолированную запись в кеше. TanStack DB добавляет недостающий реляционный слой — обеспечивая объединения, фильтры и реактивные обновления по всему графу данных.

Магия заключается в дифференциальном потоке данных (differential dataflow) — технике, которая пересчитывает только те части запросов, которые действительно изменились. Это означает, что обновление одной строки в коллекции из 100 000 элементов занимает всего 0,7 мс на M1 Pro — достаточно быстро, чтобы полностью устранить подтормаживания интерфейса.

Основные концепции: коллекции, живые запросы и оптимистичные мутации

Коллекции: основа ваших данных

Коллекции — это типизированные наборы объектов, которые могут заполняться из любого источника — REST API, GraphQL или движков синхронизации, таких как ElectricSQL. Они оборачивают ваши существующие вызовы useQuery:

const todoCollection = createCollection(
  queryCollectionOptions({
    queryKey: ['todos'],
    queryFn: async () => api.todos.getAll(),
    getKey: (item) => item.id,
    schema: todoSchema
  })
)

Это выглядит знакомо, потому что строится на паттернах TanStack Query. Разница? Коллекции нормализуют ваши данные и обеспечивают реактивные запросы по связям.

Живые запросы: реактивность без шаблонного кода

Живые запросы автоматически обновляются при изменении базовых данных — без ручной инвалидации кеша, без цепочек useMemo:

const { data: activeTodos } = useLiveQuery((query) =>
  query
    .from({ todos: todoCollection })
    .where(({ todos }) => eq(todos.completed, false))
)

Когда статус любой задачи меняется, этот запрос обновляется менее чем за 1 мс. Движок дифференциального потока данных гарантирует, что пересчитываются только затронутые строки, а не весь набор данных.

Оптимистичные мутации: мгновенные обновления UI

TanStack DB автоматически обрабатывает оптимистичные обновления со встроенным откатом при ошибке:

// До: ручные оптимистичные обновления с TanStack Query
const mutation = useMutation({
  mutationFn: createTodo,
  onMutate: async (newTodo) => {
    // 20+ строк шаблонного кода...
  }
})

// После: TanStack DB
todoCollection.insert({
  id: uuid(),
  text: 'Ship faster',
  completed: false
})

Мутация появляется в вашем UI мгновенно и автоматически откатывается, если сервер её отклоняет. Никакого шаблонного кода, никакого ручного управления состоянием.

Почему дифференциальный поток данных меняет всё

Традиционное управление состоянием заставляет идти на компромисс: либо делать много API-вызовов (медленная сеть), либо фильтровать большие наборы данных на клиенте (медленный рендеринг). Дифференциальный поток данных открывает третий вариант: загрузить нормализованные данные один раз, а затем выполнять молниеносные инкрементные объединения в браузере.

Такие компании, как Linear и Figma, достигают мгновенных интерфейсов благодаря собственным системам дифференциальных обновлений. TanStack DB демократизирует этот подход, делая реактивность за доли миллисекунды доступной для любого JavaScript-приложения.

Локальная синхронизация с ElectricSQL

Хотя TanStack DB отлично работает с REST и GraphQL, он по-настоящему раскрывается в паре с движками синхронизации. ElectricSQL, например, использует логическую репликацию Postgres для потоковой передачи изменений непосредственно клиентам:

const todoCollection = createCollection(
  electricCollectionOptions({
    shapeOptions: {
      url: 'http://localhost:3003/v1/shape',
      params: { table: 'todos' }
    },
    getKey: (item) => item.id
  })
)

Теперь любое изменение в вашей базе данных Postgres мгновенно обновляет всех подключенных клиентов — без настройки WebSocket, без ручной рассылки. Этот паттерн локальной синхронизации полностью устраняет сетевую задержку из пользовательских взаимодействий.

Путь постепенного внедрения

TanStack DB надстраивается поверх вашей существующей настройки TanStack Query. Начните с одной коллекции, сохраните текущие API-вызовы и мигрируйте постепенно:

  1. Оберните существующий запрос в коллекцию
  2. Замените отфильтрованные массивы живыми запросами
  3. Упростите мутации с автоматическими оптимистичными обновлениями
  4. (Опционально) Добавьте синхронизацию в реальном времени с ElectricSQL

Каждый шаг улучшает производительность и снижает сложность. Никаких масштабных переписываний не требуется.

Заключение

TanStack DB привносит дифференциальный поток данных в JavaScript, обеспечивая реактивные интерфейсы, которые обновляются за микросекунды, а не миллисекунды. Расширяя TanStack Query коллекциями и живыми запросами, он устраняет традиционные компромиссы между эффективностью сети и производительностью рендеринга.

Хотя TanStack DB всё ещё находится в бета-версии, он готов для изучения и постепенного внедрения. Начните с одной коллекции в некритичной функции и ощутите разницу, которую обновления за доли миллисекунды привносят в восприятие вашего приложения. Ваши пользователи — и ваша кодовая база — будут вам благодарны.

Часто задаваемые вопросы

Да, TanStack DB может заменить Redux или Zustand для управления клиентским состоянием. Он обрабатывает как серверное, так и клиентское состояние через коллекции и живые запросы. Однако рекомендуется постепенное внедрение для минимизации рисков на этапе бета-версии.

В отличие от ORM, которые фокусируются на абстракции базы данных, TanStack DB — это реактивное клиентское хранилище с дифференциальным потоком данных. Он работает в браузере, обеспечивая обновления за доли миллисекунды без обращений к серверу, сохраняя при этом типобезопасность и реляционные возможности.

TanStack DB автоматически откатывает оптимистичные обновления при сбое серверных мутаций. UI возвращается к предыдущему состоянию без ручного вмешательства. Вы можете опционально добавить обработчики ошибок для отображения обратной связи пользователю или логики повторных попыток.

Находясь в бета-версии, TanStack DB стабилен для постепенного внедрения в некритичных функциях. Начните с изолированных компонентов и расширяйте использование по мере роста уверенности. Основные концепции надёжны, даже если конкретные API могут эволюционировать до стабильного релиза.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay