1

My application has a user input a query, then fetches the response data and is also cached.

For each cache data, I want to display a button for every previous query that users can click to again load that data on the screen.

Let's say I first input the id 1, then the data is cached and rendered. When I log my cached data with Object.values(cacheData.queriesMap) I receive {["rickandmorty",0]: Query, ["rickandmorty","1"]: Query}. I now want to iterate through my cached data and display each individual query.

// <Home />
const cachedCharacters = Object.values(cacheData.queriesMap).map(character => (
    <button>{character.state.data.name}</button>
))

return (
    <div>
      {cachedCharacters}
    </div>
)

However, I receive a TypeError: Cannot read property 'name' of undefined. I suspect the reason for this error is because the first query is ["rickandmorty",0], a non-existing item that the application had fetched upon mounting.

undefined from initial fetch

I then set up my application to disable fetching upon component mount.

// <Home/>
const { isLoading, error, data } = useQuery(
    ["rickandmorty", idQuery],
    handleRickAndMortyFetch,
    {
      enabled: false || idQuery !== 0,
  );

Yet, the application still makes the initial fetch upon mounting. If I first input the id 1, I again receive {["rickandmorty",0]: Query, ["rickandmorty","1"]: Query}.

If the initial fetch is what's preventing each individual cache data to be rendered, how do I disable the initial fetch if enabled: false is not working? If it's a different issue preventing each individual cache data to be rendered, kindly suggest a solution. https://codesandbox.io/s/rick-and-morty-render-cache-data-8dv6y

1 Answer 1

2

Your code is correct. The initial query in the dev-tools you are seeing doesn't necessarily mean it is getting fetched. If you look through the state of the idQuery 0, there are no counts of it having its' data/error being updated. It's just in an idle state.

I suggest you try and filter your cacheData.queriesMap initially before mapping to make sure that your characters have data. You can either check the state.data or make sure the query has a state.status === 'success'. Or the easiest way might be to just show which queries already have data.

  const cachedCharacters = Object.values(
    cacheData.queriesMap
  ).map((character, index) => (
    <>
      {character.state.data ? (
        <button key={`${character.state.data.name}${index}`}>
          {character.state.data.name}
        </button>
      ) : null}
    </>
  ));
Sign up to request clarification or add additional context in comments.

1 Comment

I now see that idQuery 0 is an idle state. Thank you for the clear solution! @Leomar-amiel

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.