Доки по разработке
This project is maintained by teniryte
Эта глава закрывает две частые production-проблемы:
По умолчанию TanStack Query старается сохранить старые ссылки там, где данные фактически не изменились.
Что это даёт:
useMemo и useCallbackЭто работает лучше всего с JSON-compatible данными.
Query result использует Proxy и ререндерит компонент только если поменялось реально прочитанное поле.
Хорошо:
const query = useQuery(todoOptions(id))
return <TodoView todo={query.data} loading={query.isFetching} />
Плохо:
const { data, ...rest } = useQuery(todoOptions(id))
Object rest destructuring ломает tracked-properties optimization.
selectselect помогает подписаться только на нужный срез:
const todoCountQuery = useQuery({
...todosOptions(),
select: (data) => data.length,
})
Если список изменился, но длина нет, компонент не будет ререндериться из-за остальных деталей.
Важно: стабилизируйте select, если он зависит от ссылок.
const selectVisibleTodos = useCallback(
(data: Todo[]) => data.filter((todo) => todo.visible),
[],
)
notifyOnChangePropsПо умолчанию tracked props уже дают хороший результат. Но иногда нужно тонко управлять:
useQuery({
...todosOptions(),
notifyOnChangeProps: ['data', 'error'],
})
Используйте только если действительно понимаете, что оптимизируете.
Важно помнить:
data внутри него стабилизируется настолько, насколько возможноПоэтому не стоит мемоизировать сам объект query, если вам важны именно данные.
Waterfall возникает, когда запросы стартуют не параллельно, а цепочкой:
Даже если каждый запрос быстрый, суммарное время резко растёт.
useQuery без необходимостиawait Promise.all([
queryClient.ensureQueryData(userOptions(userId)),
queryClient.ensureQueryData(statsOptions(userId)),
queryClient.ensureQueryData(activityOptions(userId)),
])
Либо несколькими useQuery, либо useQueries.
Особенно в Next.js App Router, Remix, TanStack Router.
Если projectId и statsId уже известны, не надо ждать detail query ради их запуска.
Для каждой страницы задайте себе три вопроса:
select, если компоненту не нужен весь ответ.