Home > Back-end >  how to avoid undefined using React Query (useQuery) for fetch data?
how to avoid undefined using React Query (useQuery) for fetch data?

Time:10-13

when I console data for the first console, it's given me undefined.

somethings likes:

log: undefined

but if I trying to again console.log it working fine and give me values for the API.

here is my code below:

   const fetchPosts = () => {
        const fP = devices?.map(async (id) => {
            const { data } = await axios.get(`https://jsonplaceholder.typicode.com/users`, myHeaders);
            return [data?.data.id];
        })
        return fP;
    };
    
   
    const { data } = useQuery('post', fetchPosts);
 console.log(data);

how can i avoid undefined for the first console.log?

anyone can help me to solve this issues.

Thankyou for your trying in advance!

CodePudding user response:

This is normal and expected. data will always be undefined on first render since the query data has not been fetched yet and the cache for that particular query key is empty at this point. However, if you have some partial or "fake" data to display while the actual data is being fetched in the background, you can use placeholderData option in useQuery so the query behaves as if it already has data.

This can be useful in cases where you want to show the content layout as quick as possible while the fetching is in progress. You can think about it as a loading skeleton.

The placeholder data can come from different sources (a simple value, a function, cache, etc.)

Example of placeholder data as a value:

function Todos() {
  const result = useQuery(['todos'], () => fetch('/todos'), {
    placeholderData: placeholderTodos,
  })
}

Reference:

For more information you can check the documentation.

CodePudding user response:

To avoid undefined you need to check for loading and error. Here's a simple way to fetch list of users.

import { useQuery } from "react-query";
import axios from "axios";

function Test() {
  const fetchUser = async () => {
    const response = await axios.get(
      "https://jsonplaceholder.typicode.com/users"
    );
    return response.data;
  };

  const { data, isLoading, error } = useQuery("user", fetchUser);

  if (isLoading) return "Loading...";
  if (error) return "An error has occurred: "   error.message;

  return (
    <div>
      <h1>Users</h1>

      {data.map((item) => {
        return (
          <div key={item.id}>
            <h1>{item.name}</h1>
            <h1>{item.email}</h1>
          </div>
        );
      })}
    </div>
  );
}

export default Test;

I notice you have named your function fetchPost. Suppose you want to fetchPost as well. Here's how I would do it in a simple way.

import { useQuery } from "react-query";
import axios from "axios";

function Test() {
  const fetchUser = async () => {
    const response = await axios.get(
      "https://jsonplaceholder.typicode.com/users"
    );
    return response.data;
  };

  const fetchPosts = async () => {
    const response = await axios.get(
      "https://jsonplaceholder.typicode.com/posts"
    );
    return response.data;
  };

  const { data, isLoading, error } = useQuery("user", fetchUser);

  const {
    data: posts,
    isLoading: postLoading,
    error: postError,
  } = useQuery("posts", fetchPosts);

  if (isLoading) return "Loading...";
  if (error) return "An error has occurred: "   error.message;

  if (postLoading) return <h1>Loading...</h1>;
  return (
    <div>
      <h1>*************Users*************</h1>

      {data.map((item) => {
        return (
          <div key={item.id}>
            <h1>{item.name}</h1>
            <h1>{item.email}</h1>
          </div>
        );
      })}

      <h1>*************POST*************</h1>
      {posts.map((item) => {
        return (
          <div key={item.id}>
            <h1>{item.title}</h1>
            <h1>{item.body}</h1>
          </div>
        );
      })}
    </div>
  );
}

export default Test;
I hope this answers your question.

CodePudding user response:

I'm assuming the first time you try to access your { data }, your fetch requests haven't finished running yet.

React is going to finish rendering the component, while any fetch requests are happening in the background. Since nothing has being returned from your React Query yet, the variable you set for your query data is still undefined the first time the component renders.

React Query has an isFetched method attached to the the query object. You could use a conditional to only continue when your data has been fetched.

if(data.isFetched){
  console.log(data)
} else {
  console.log("loading")
}
  • Related