通过数据哈希匹配阻止React Query中的数据刷新



我使用React-Query调用的API以如下形式返回一组数据和该数据的哈希键:

{
orders:[{order1},{order2},....]
dataHash:number
}

我使用这个dataHash来检查useQuery()选项内的请求结果是否相等,以使reach查询更容易在自己的数据集上比较大数据集,如下所示:

isDataEqual:(oldData, newData)=>oldData?.dataHash === newData.dataHash, //do not refresh page if hashes are equal

API还有一个功能,允许在dataHash与请求中的数据集匹配时不发送数据集。在这种情况下,它只返回以下内容:

{
orders:[] //empty array here
dataHash:number
}

但由于我的比较函数只查看dataHash,所以不会使用新数据,一切都会按预期进行。

我目前遇到的问题是,我似乎无法在react查询中找到一种内置的方法来保存旧请求中的dataHash,以便将其作为参数传递到新请求中。理想情况下,我希望看到react查询将旧数据传递到请求函数中,这样我就可以自己进行比较,但这不是一个选项。

我还发现它将某种元数据对象传递到请求查询中,但我还没有找到针对任何特定请求更改此对象的方法。我是不是错过了什么?

const getOrders = async (metadata:any): Promise<ShowOrdersResponse> => {
console.log(metadata) //this holds the "meta" object and query keys

const request: ShowOrdersRequest = {
searchParam: mySearchParam,
dataHash: 12//dataHash
};
const {data} = await secureAxios.post<ShowOrdersResponse>(ApiEndpoints.ShowOrders, request)
return data;
}
const {data} = useQuery<ShowWorkOrdersResponse>(['workorders', mySearchParam], getOrders, {
cacheTime: 30000,
refetchInterval: 5000,
isDataEqual:(oldData, newData)=>oldData?.dataHash === newData.dataHash, //do not refresh page if hashes are equal, this works as charm
meta:{dataHash:555}  //I am able to pass this "meta" object into the request query, but cannot mutate it
});

第1版:我实施了建议的解决方案,但它仍然没有完全解决问题。目前,我正在将服务器返回的dataHash保存在组件状态中,如下所示:

onSuccess: (data) => setDataHash(data?.data.dataHash)

后来,我用不同的搜索参数调用useQuery((,它认为这是一个完全不同的请求,但由于我发送的是相同的哈希,所以没有得到任何结果。isDataEqual((返回false,并用空结果更新数据。

我认为我需要一种能力来保存每个请求的dataHash(从未定义开始(,但这意味着queryFn需要访问";oldData.data.dataHash";发送它。目前我不知道如何做到这一点。

queryFn返回的任何内容都将被放入查询缓存中,因此可以作为从useQuery返回的data以及在isDataEqual函数上使用(因为传递的是相同的data(。所以我会这么做:

const getOrders = async (): Promise<ShowOrdersResponse> => {

const request: ShowOrdersRequest = {
searchParam: mySearchParam,
dataHash: 12
};
const { data } = await secureAxios.post<ShowOrdersResponse>(ApiEndpoints.ShowOrders, request)
return {
data,
dataHash
}
}
useQuery(
['workorders', mySearchParam],
getOrders,
{
isDataEqual:(oldData, newData) => oldData?.dataHash === newData.dataHash,
}
)

当然,一个缺点是您需要在组件中打开data.data,但您可以使用select函数来解决这个问题:

useQuery(
['workorders', mySearchParam],
getOrders,
{
isDataEqual:(oldData, newData) => oldData?.dataHash === newData.dataHash,
select: data => data.data
}
)

这是因为isDataEqual直接从缓存中传递数据,而每个组件(观察者(在运行select后都会传递数据。所以基本上,您只需要传递dataHash,这样您就可以在isDataEqual中使用它。

我的解决方案是修改queryFn,使其接收缓存的数据作为第二个可选参数,并在适当的时候返回。请参阅相关问题中的详细信息。

最新更新