2021-12-30

Prevent data refresh in React-Query by data hash matching

The API that I hit with React-Query returns a set of data and a hash key for this data in a form like so:

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

I Use this dataHash to check if the request results are equal inside useQuery() options to make it easy for reach-query to compare big datasets on it's own like so:

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

The API also has a feature that allows not to send a dataset if the dataHash matches with the one in a request. In such case it only returns the following:

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

But since my compare function only looks at dataHash the new data will not be used and everything will work as expected.

The problem I have currently is that I cannot seem to find a built-in way in react-query to save the dataHash from the old request so that it is being passed as a parameter into the new one. Ideally I would like to see react-query passing the old data into the request function so I can compare it myself but this is not an option.

I also found that it passes some sort of metadata object into the request query, but I have not found a way to mutate this object for any particular request. Am I missing Something here?

  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
  });

Edit1: I implemented the proposed solution but it still does not solve the problem completely. Currently I am saving the returned dataHash from server inside the component state like so:

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

Later I call useQuery() with different search params, which it considers as a totally different request, yet since I'm sending the same hash I get no results back. isDataEqual() returns false and updates the data with empty result.

I think I need an ability to save the dataHash per-request(starting with undefined) but this means that queryFn needs to have access to "oldData.data.dataHash" to send it in. and currently i do not see how this can be done.



from Recent Questions - Stack Overflow https://ift.tt/3sI9V25
https://ift.tt/eA8V8J

No comments:

Post a Comment