读写实战
主链路:Query + Mutation + Invalidate
Section titled “主链路:Query + Mutation + Invalidate”'use server';
export async function createTodoAction(title: string) { await fetch('https://example.com/api/todos', { method: 'POST', body: JSON.stringify({ title }), });}// client componentimport { useMutation, useQuery } from '@iostore/react';
const todos = useQuery({ key: ['todos'], queryFn: ({ signal }) => fetch('/api/todos', { signal }).then((r) => r.json()),});
const createTodo = useMutation({ mutationFn: (title: string) => fetch('/api/todos', { method: 'POST', body: JSON.stringify({ title }), }).then((r) => r.json()), onSuccess: () => void todos.invalidate(),});useIO 联动本地状态
Section titled “useIO 联动本地状态”import { io } from '@iostore/store';import { useIO, useQuery } from '@iostore/react';
const localState = io({ tab: 'all', page: 1 });
function Example() { const local = useIO(localState); const q = useQuery({ key: ['todos', local.tab, local.page], queryFn: ({ signal }) => fetch('/api/todos', { signal }).then((r) => r.json()), }); return <div>{q.isFetching ? 'loading' : 'ready'}</div>;}- 远端真值由 Query 管理,本地交互状态由 useIO(Svelte 对应 store 适配)管理。
- 本地状态驱动查询时,参数必须完整进入
key。 - 输入高频场景建议结合
batch与调度策略。
相关 API
Section titled “相关 API”失败处理与回滚建议
Section titled “失败处理与回滚建议”- 对网络抖动使用有限重试;对业务错误直接暴露并停止重试。
- 有乐观更新时,在
onMutate保存快照,在onError回滚。 - 取消(AbortError)不应写入错误看板。
Query Key 设计规范
Section titled “Query Key 设计规范”- key 只放可序列化数据,且顺序稳定。
- 把筛选条件、租户、分页参数全部纳入 key。
- 不要在 key 中放函数、类实例、DOM 节点。
常见错误对照
Section titled “常见错误对照”错误:key 不含参数
Section titled “错误:key 不含参数”// 错误:tenantId 未进入 keykey: ['users'];推荐:key 与请求参数一一对应
Section titled “推荐:key 与请求参数一一对应”key: ['users', tenantId];错误:写后手工猜测同步
Section titled “错误:写后手工猜测同步”// 错误:直接本地拼补丁,长期会偏离服务端onSuccess: (item) => { cache.push(item);};推荐:写后统一失效刷新
Section titled “推荐:写后统一失效刷新”onSuccess: async () => { await todos.invalidate();};