You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中如何用RTK Query对列表项批量执行GraphQL查询?

解决方案:封装RTK Query批量查询自定义钩子

要实现你需要的useSaved钩子,核心思路是利用RTK Query的查询函数或者懒查询结合useEffect处理批量请求,同时完全复用已有的baseQuery,不会违反React钩子规则。

步骤1:确认API Slice结构

假设你的API slice已经定义了两个核心查询:

  • getSaved:返回已保存项的ID列表(对应钩子useGetSavedQuery)
  • getItemDetail:根据单个ID查询项详情(对应自动生成的查询函数api.endpoints.getItemDetail.initiate)

步骤2:封装useSaved自定义钩子

下面是完整实现代码,自动处理ID列表获取、批量详情查询,并合并状态返回给调用方:

import { useEffect, useState } from 'react';
import { useGetSavedQuery } from './your-api-slice';
import { api } from './your-api-slice'; // 导入整个API slice实例

export const useSaved = () => {
  // 1. 获取已保存的ID列表
  const { data: savedIds, isLoading: idsLoading, error: idsError } = useGetSavedQuery();
  
  // 2. 存储详情数据与合并后的全局状态
  const [savedItems, setSavedItems] = useState([]);
  const [isLoading, setIsLoading] = useState(idsLoading);
  const [error, setError] = useState(idsError);

  // 3. ID列表更新时批量请求详情
  useEffect(() => {
    if (!savedIds || savedIds.length === 0) {
      setSavedItems([]);
      setIsLoading(false);
      return;
    }

    setIsLoading(true);
    setError(null);

    // 复用RTK Query的查询逻辑,直接调用baseQuery
    const fetchDetails = async () => {
      try {
        // 并行发起所有详情查询
        const detailPromises = savedIds.map(async (id) => {
          // 调用endpoint的initiate方法,返回Promise并获取数据
          const result = await api.endpoints.getItemDetail.initiate(id).unwrap();
          return result;
        });

        const details = await Promise.all(detailPromises);
        setSavedItems(details);
      } catch (err) {
        setError(err);
      } finally {
        setIsLoading(false);
      }
    };

    fetchDetails();
  }, [savedIds]);

  // 4. 返回合并后的状态,调用方无需关心内部逻辑
  return {
    data: savedItems,
    isLoading,
    error,
  };
};

方案细节说明

  • 复用baseQuery:通过api.endpoints.getItemDetail.initiate直接调用RTK Query生成的查询函数,完全复用API slice中配置的GraphQL请求逻辑、缓存、拦截器等。
  • 规避钩子规则:不在循环中调用React钩子,而是通过useEffect监听ID列表变化,在副作用中批量执行查询。
  • 状态合并:将ID查询和详情查询的加载、错误状态合并,调用方使用体验和普通RTK Query钩子一致。

优化:利用RTK Query缓存

如果同一个ID可能被重复查询,RTK Query会自动返回缓存数据。若需要强制刷新,可给initiate方法传入参数:

const result = await api.endpoints.getItemDetail.initiate(id, { forceRefetch: true }).unwrap();

调用示例

使用方只需引入钩子直接使用即可:

const { data: savedItems, isLoading, error } = useSaved();

if (isLoading) return <LoadingSpinner />;
if (error) return <ErrorText>{error.message}</ErrorText>;

return (
  <FlatList
    data={savedItems}
    renderItem={({ item }) => <ItemCard item={item} />}
  />
);

内容的提问来源于stack exchange,提问作者Ethan Powers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 12:15:34