TanStack 家族条目式速查:Query v5 / Table v9 / Router / Form。
1. useQuery 核心
描述
queryKey 是身份(键变即重取);staleTime 新鲜期;v5 用 isPending。
语法和示例
const { data, isPending, isError, error } = useQuery({
queryKey: ['posts', { page }],
queryFn: () => fetch(`/api/posts?page=${page}`).then(r => r.json()),
staleTime: 60_000,
gcTime: 5 * 60_000, // v4 的 cacheTime 已更名
});2. useMutation 与失效
描述
onSuccess 里 invalidate 触发重取;mutationFn 收变量。
语法和示例
const qc = useQueryClient();
const add = useMutation({
mutationFn: (body) => fetch('/api/posts', {
method: 'POST', body: JSON.stringify(body),
}),
onSuccess: () => qc.invalidateQueries({ queryKey: ['posts'] }),
});3. 乐观更新套路
描述
onMutate 先改缓存并快照;onError 回滚;onSettled 兜底失效。
语法和示例
const todo = useMutation({
mutationFn: patchTodo,
onMutate: async (next) => {
await qc.cancelQueries({ queryKey: ['todos'] });
const prev = qc.getQueryData(['todos']);
qc.setQueryData(['todos'], (old) => replace(old, next));
return { prev };
},
onError: (_e, _v, ctx) => qc.setQueryData(['todos'], ctx?.prev),
onSettled: () => qc.invalidateQueries({ queryKey: ['todos'] }),
});4. useInfiniteQuery
描述
getNextPageParam 返回下一页标识或 null 终止;data.pages 是二维。
语法和示例
const q = useInfiniteQuery({
queryKey: ['feed'],
queryFn: ({ pageParam }) => fetch(`/feed?cursor=${pageParam}`).then(r => r.json()),
initialPageParam: 0,
getNextPageParam: (last) => last.nextCursor ?? null,
});
q.data?.pages.flat(); // 摊平全部页5. Table v9 入口
描述
useTable + tableFeatures 必填;行模型与排序函数显式注册。
语法和示例
const features = tableFeatures({
rowSortingFeature,
sortedRowModel: createSortedRowModel(),
sortFns: { alphanumeric: sortFns.alphanumeric },
});
function T({ data }: { data: Person[] }) {
const columns = useMemo(buildColumns, []); // 纯常量放组件外
const table = useTable({ features, data, columns });
// 渲染经 flexRender(h.column.columnDef.cell, h.getContext())
}6. columnHelper 列定义
描述
accessor 键或函数;header/cell 是渲染函数;v9 全部函数需注册。
语法和示例
const columnHelper = createColumnHelper<Person>();
const buildColumns = () => columnHelper.columns([
columnHelper.accessor('name', { header: '姓名' }),
columnHelper.accessor('age', {
header: '年龄',
cell: (info) => info.getValue() + ' 岁',
sortingFn: 'alphanumeric', // 需在 features.sortFns 注册
}),
]);7. 排序交互
描述
表头 getToggleSortingHandler;顺序 asc → desc → none。
语法和示例
<th onClick={h.column.getToggleSortingHandler()}>
{flexRender(h.column.columnDef.header, h.getContext())}
{{ asc: ' ↑', desc: ' ↓' }[h.column.getIsSorted() as string] ?? ''}
</th>8. Router 路由树
描述
createRoute 声明式拼树;类型由父路由推导。
语法和示例
const root = createRootRoute();
const home = createRoute({ getParentRoute: () => root, path: '/', component: Home });
const tree = root.addChildren([home]);
const router = createRouter({ routeTree: tree });
// 嵌在已有 Provider 内:<RouterProvider router={router} />9. Form v1 无状态
描述
form.Field 渲染属性;错误分层:字段在 field.state.meta.errors。
语法和示例
const form = useForm({
defaultValues: { email: '' },
validators: { onSubmit: zodSchema },
});
<form.Field name="email">{(field) => (
<input value={field.state.value}
onChange={(e) => field.handleChange(e.target.value)} />
)}</form.Field>
// 表单级错误在 form.state;提交态用 <form.Subscribe selector={(s) => s.canSubmit} />