admin管理员组文章数量:1410730
I am having issues understanding how to get useLazyQuery
to get the cached data on a second time the component is mounted.
Imagine the following:
...
const [trigger, { data }] = api.useLazyQuery(); // assume it takes 10 seconds to run
const exists: boolean = !!data;
const onClickHandler = (e) => { trigger(e.target.value) }; // handler for a button that takes an argument
React.useEffect(() => {
console.log(data); // it shows undefined
}, [data]);
return <>{exists && <>Result data: {data}</>}</>
...
So basically, the first time the component is mounted, the user clicks a button to trigger the run of api.useLazyQuery()
, get the data and show the results after 10 seconds. Good.
Now on the second time the component is mounted, it should just simply show the data. It doesn't because data
is undefined. But if the user clicks the button, it shows the results right away, it didn't wait for those 10 seconds. This means that the data was returned from the store/cache.
So how do I go about doing this so that I can immediately show the data after the second time the component is mounted, without having the user clicking the button just to trigger the trigger
function?
Edit: updating the example to reflect the fact that trigger
takes an input parameter. There is a proposal to use fixedCacheKey
but that essentially keeps the same cache for the same endpoint, regardless of the input argument.
I am also open to other solutions if there is no way around the rtk.
I am having issues understanding how to get useLazyQuery
to get the cached data on a second time the component is mounted.
Imagine the following:
...
const [trigger, { data }] = api.useLazyQuery(); // assume it takes 10 seconds to run
const exists: boolean = !!data;
const onClickHandler = (e) => { trigger(e.target.value) }; // handler for a button that takes an argument
React.useEffect(() => {
console.log(data); // it shows undefined
}, [data]);
return <>{exists && <>Result data: {data}</>}</>
...
So basically, the first time the component is mounted, the user clicks a button to trigger the run of api.useLazyQuery()
, get the data and show the results after 10 seconds. Good.
Now on the second time the component is mounted, it should just simply show the data. It doesn't because data
is undefined. But if the user clicks the button, it shows the results right away, it didn't wait for those 10 seconds. This means that the data was returned from the store/cache.
So how do I go about doing this so that I can immediately show the data after the second time the component is mounted, without having the user clicking the button just to trigger the trigger
function?
Edit: updating the example to reflect the fact that trigger
takes an input parameter. There is a proposal to use fixedCacheKey
but that essentially keeps the same cache for the same endpoint, regardless of the input argument.
I am also open to other solutions if there is no way around the rtk.
Share edited Mar 8 at 21:38 renatodamas asked Mar 7 at 22:09 renatodamasrenatodamas 19.7k8 gold badges41 silver badges59 bronze badges 1- This is normal, isn't it? When a user action triggers a data query – whether fetching from the server or retrieving cached data – the component naturally reinitializes. If you want the component to retain its state when revisited (preserving its appearance from the first exit), you should cache the component. – yuanyxh Commented Mar 8 at 3:54
1 Answer
Reset to default 1Issue
The issue you are observing is due to the fact that when the component remounts it is getting a new "instance" of the lazy query hook and trigger function. The query endpoint data is cached in the store, but the subscription is cleared when the component unmounts, or rather, a new subscription will be created the first time the trigger function is called. This is when the subscription and cached data are coupled.
Solution Suggestion
- You can accept this as the default expected behavior of query endpoints and lazy hooks and be done with it and move on.
- You can use a mutation endpoint and a fixed cache key so any cached data will be immediately available to any consumers.
Example:
Update from a builder.query
to builder.mutation
endpoint definition:
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: "https://jsonplaceholder.typicode/",
}),
endpoints: (build) => ({
getPosts: build.mutation({ // <-- mutation
query: () => "posts",
}),
}),
});
export const { useGetPostsMutation } = api;
Call the mutation hooks and provide a fixedCacheKey
value so all instances of that hook will access the same cached endpoint data.
import { useGetPostsMutation } from "./api.slice";
import { useEffect, useState } from "react";
const Component = () => {
const [trigger, { data }] = useGetPostsMutation({
fixedCacheKey: "keep" // *
});
useEffect(() => {
console.log({ data });
}, [data]);
const clickHandler = () => {
trigger();
};
return (
<>
<button type="button" onClick={clickHandler}>
Trigger Query
</button>
<div>Data: {....data...}</div>
</>
);
};
*Note: I used "keep"
, but any sufficiently unique cache key value can be used.
Demo
本文标签: reactjsHow to get cached data in RTKQuery using useLazyQueryStack Overflow
版权声明:本文标题:reactjs - How to get cached data in RTK-Query using useLazyQuery? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744908272a2631755.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论