ln09nv2
ln09nv2

Reputation: 1343

How to access cache to display data with React Query?

My application has a user input an id to send as a request and the response data that matches that id is rendered and also cached.

I'd like to access the cache so that I can also display its data so that a user can see their previous queries. However, I receive this error with my attempts. TypeError: Cannot read property 'getQueryData' of undefined.

The following are my attempts to access the cache.

console.log(queryCache.getQueryData("rickandmorty"))
console.log(queryCache.getQueryData(["rickandmorty", idQuery]))
console.log(queryClient.getQueryData("rickandmorty"))
console.log(queryClient.getQueryData(["rickandmorty", idQuery]))

Please let me know what I'm doing wrong. I'm using version "react-query": "^3.13.0" https://codesandbox.io/s/rick-and-morty-2gy8r?file=/src/App.js

const [idQuery, setIdQuery] = useState(0);
const [rickAndMortyCharacter, setRickAndMortyCharacter] = useState({});
const queryRef = useRef(null);
const { register, handleSubmit, errors, setValue, watch } = useForm({
  resolver: yupResolver(searchSchema)
});
const formId = watch("rickAndMortyId");

const handleRickAndMortyFetch = () => {
  return delay()
    .then(() => axios(`https://rickandmortyapi.com/api/character/${idQuery}`))
    .then((res) => setRickAndMortyCharacter(res.data));
};

const { isLoading, error } = useQuery(
  ["rickandmorty", idQuery],
  handleRickAndMortyFetch,
  {
    refetchOnWindowFocus: false,
    enabled: idQuery !== 0,
    useErrorBoundary: true
  }
);
const disable = isLoading || parseFloat(formId) === idQuery;
const onSubmit = (formData) => {
  setIdQuery(formData.rickAndMortyId);
};

return (
  <div>
    <ErrorBoundary
      FallbackComponent={ErrorFallback}
      onReset={() => {
        queryRef.current.focus();
      }}
      resetKeys={[idQuery]}
    >
      <div>
        <form onSubmit={handleSubmit(onSubmit)}>
          <h3>Rick and Morty</h3>
          <input
            type="number"
            name="rickAndMortyId"
            placeholder="Between 1 and 671"
            ref={register}
            disabled={isLoading}
          />
          {errors.rickAndMortyId && <span>This field is required</span>}
          {error && <p>Error occurred: {error.message}</p>}
          <button type="submit" disabled={disable}>
            Search Character
          </button>
        </form>
        <button
          onClick={() => {
            const randomId = getRandomRickAndMortyCharacterId();
            setValue("rickAndMortyId", randomId);
            setIdQuery(randomId);
          }}
        >
          Random
        </button>
      </div>
      <div>
        {isLoading && <p>Loading...</p>}
        <RickAndMortyInfo rickAndMortyCharacter={rickAndMortyCharacter} />
      </div>
      <ReactQueryDevtools initialIsOpen={true} />
    </ErrorBoundary>
  </div>
);

Upvotes: 4

Views: 13719

Answers (1)

NearHuscarl
NearHuscarl

Reputation: 81555

In this code:

const [rickAndMortyCharacter, setRickAndMortyCharacter] = useState({});
const handleRickAndMortyFetch = () => {
  return delay()
    .then(() => axio('...'))
    .then((res) => setRickAndMortyCharacter(res.data));
};

const { isLoading, error } = useQuery(
  ["rickandmorty", idQuery],
  handleRickAndMortyFetch
);

After a successful fetch, you assign the result to a local state instead of handing to react-query, so it doesn't know what data should be cached. You need to return the result like this:

const handleRickAndMortyFetch = () => {
  return delay()
    .then(() => axio('...'))
    .then((res) => res.data); // return instead of calling setState()
};

So react-query can 'catch' it and put it into cache. The next step is to remove your local state rickAndMortyCharacter and reference data instead. It is the resolved result after a successful fetch.

const {
  isLoading,
  error,
  data // remove rickAndMortyCharacter and reference this instead
} = useQuery(
  ["rickandmorty", idQuery],
  handleRickAndMortyFetch
);

Only then can you log the cache as normal:

queryClient.getQueryData(["rickandmorty", 518]);

Live Demo

Edit 66864316/how-to-access-cache-to-display-data-with-react-query

Upvotes: 4

Related Questions