TypeScript中React Hooks多ID查询改造遇TS6198错误求助
解决React Hooks批量查询数据的问题
你当前的代码存在两个核心问题:
- 违反React Hooks规则:不能在
forEach循环内部调用Hooks(如useGetCustomerOrdersByItemQuery),React要求Hooks必须在组件/自定义Hooks的顶层调用,否则会导致状态管理混乱。 - 变量作用域问题:
forEach内部定义的data、customerData、loading都是局部变量,外部无法访问,因此后续的mapped数组为空,同时TypeScript提示“所有解构元素未使用”——因为这些变量在循环内没有被有效利用。
以下是符合规则且能实现需求的正确方案(假设你使用的是Apollo Client,若为其他GraphQL/数据查询库,思路可复用):
import { useQueries } from '@apollo/client'; export const useViewCustomerOrderData = (ids: string[]) => { // 过滤无效id并转换为数字类型 const validItemIds = ids.filter(id => id).map(id => Number(id)); // 批量执行每个id对应的订单查询 const itemQueryResults = useQueries({ queries: validItemIds.map(itemId => ({ query: useGetCustomerOrdersByItemQuery.document, variables: { itemId }, })), }); // 收集所有返回的poIds并去重,避免重复查询 const allPoIds = Array.from( new Set( itemQueryResults.flatMap(result => result.data?.getCustomerOrdersByItem?.map(p => p?.customerOrderId) .filter((poid): poid is number => Boolean(poid)) ?? [] ) ) ); // 根据合并后的poIds查询客户订单详情 const { data: customerData, loading: customerLoading } = useGetCustomerOrdersQuery({ variables: { poIds: allPoIds }, skip: allPoIds.length === 0, }); // 映射整合最终的表格数据 const mapped: GridModel[] = customerData?.getCustomerOrders?.customerOrders?.map((p) => ({ customerOrderId: p?.id ?? undefined, warehouse: p?.site?.name ?? undefined, startShipDate: p?.expectedShipDate ?? undefined, cancelShipDate: p?.expectedReceivedDate ?? undefined, })) ?? []; // 计算全局加载状态:只要有一个查询在加载,就返回true const loading = itemQueryResults.some(res => res.loading) || customerLoading; return { data: mapped, loading, }; };
关键细节说明
useQueries批量查询:该Hook允许在顶层执行多个查询,返回结果数组,完全符合React Hooks的调用规则。- 无效id过滤:提前过滤空字符串id,避免发起无效请求。
- poIds去重:通过
Set去除重复的订单ID,减少不必要的重复查询,提升性能。 - 全局loading状态:检查所有批量查询的加载状态,加上详情查询的状态,确保返回准确的加载状态。
内容的提问来源于stack exchange,提问作者rosed
相关产品推荐
相关产品推荐

