Skip to content

useQuery 在文档示例用法下是无界请求循环:内联 options 300ms 内发出 8830 次 find #4693

Description

@os-zhuang

#4682(给 client-react 建测试基座)时,用刚建好的基座实测发现,unassigned。

现象

useQuery(object, options)options 里带任何对象/数组/函数字段 时会进入无界重取循环——而这正是它自己 TSDoc 示例的写法。

实测(jsdom + @testing-library/react,fake client 记 data.find 调用次数,渲染后静置 300ms):

用法300ms 内 find 调用次数
useQuery('todo_task', { where: { status: 'open' } }) —— 内联 options8830
const OPTS = {...} 提升到组件外,useQuery('todo_task', OPTS)1

不是「多取几次」,是以事件循环的速度永远打下去

成因

packages/client-react/src/data-hooks.tsx:

// L116constfetchData=useCallback(async(isRefetch=false)=>{},[client,object,query,resolvedFields,resolvedWhere,resolvedSort,resolvedLimit,resolvedOffset,enabled,onSuccess,onError]);// L156useEffect(()=>{fetchData();},[fetchData]);

resolvedWhere / resolvedFields / resolvedSort 直接来自 options 的解构,onSuccess / onError 同理。调用方内联传入 → 每次渲染都是新身份 → fetchData 每渲染换身份 → L156 的 effect 每渲染重跑 → setData → 重渲染 → 闭环,无出口。

useQuery('todo_task', {})(全部字段 undefined,都是原始值)不受影响——所以它一直没被发现。触发条件是传 where / fields / orderBy / onSuccess / onError 中的任意一个,也就是绝大多数真实用法。

同一形状的 useCallback 依赖链在 data-hooks.tsx:592metadata-hooks.tsx:136 也存在,需要一并核查。

影响

处置方向

不要用「让调用方自己 useMemo」当修复——文档示例就是内联写法,把正确性押在调用方的记忆力上等于没修。

按值而非按身份做依赖。可选:对 where/fields/orderBy 做稳定序列化(如 JSON.stringify 或结构化哈希)作为依赖;onSuccess/onError 存进 ref(它们是副作用回调,本就不该参与重取决策)。

修复必须带回归测试,基座已经就位(#4682 / PR #4692),断言直接用上表那两个数字的形状(内联 options 稳定后 find 只该被调用 1 次)。

复现

基座合入后,packages/client-react/ 下:

constfind=vi.fn(async()=>({data: [],total: 0}));constclient={data: { find,query: find},events: {},setLocale: vi.fn()}asunknownasObjectStackClient;functionC(){useQuery('todo_task',{where: {status: 'open'}});returnnull;}render(<ObjectStackProviderclient={client}><C/></ObjectStackProvider>);awaitnewPromise(r=>setTimeout(r,300));expect(find.mock.calls.length).toBe(1);// 实测 8830

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions