4

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

1 Answer 1

4

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

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your clear explanation! I see that my mistake was that I've set the state to the response data instead of handing it React-Query.
Could you share how would I access all previous queries in cache as opposed to the most previous request?
Please post another question, I'll answer when I have time @ln09nv2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.