开发者问题收集

如何避免使用 React Query(useQuery)获取数据时出现未定义的情况?

2022-10-13
22018

当我为第一个 console.log 控制台数据时,它给了我未定义的值。

类似的东西:

log: undefined

但如果我再次尝试使用 Ctrl s 保存文件,它工作正常并为我提供 API 的值。

在此处输入图像描述

这是我的代码:

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

如何避免第一个 console.log 未定义?

任何人都可以帮助我解决这个问题。

感谢您的提前尝试!

3个回答

为避免未定义,您需要检查加载和错误。 这是一个获取用户列表的简单方法。

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;

我注意到您已将函数命名为 fetchPost。假设您也想使用 fetchPost。下面是我以简单方式执行此操作的方法。

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;
Sanjeeb
2022-10-13

这是正常且符合预期的。由于查询数据尚未提取,并且此时该特定查询键的缓存为空,因此首次渲染时 data 将始终为 undefined 。但是,如果在后台提取实际数据时需要显示部分或“假”数据,您可以在 useQuery 中使用 placeholderData 选项,这样查询的行为就像它已经有数据一样。

如果您想在提取过程中尽快显示内容布局,这会很有用。您可以将其视为一个加载骨架。

占位符数据可以来自不同的来源(简单值、函数、缓存等)。

占位符数据作为值的示例:

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

参考:

有关更多信息,您可以查看 文档

ivanatias
2022-10-13

我假设您第一次尝试访问 { data } 时,您的获取请求尚未完成运行。

React 将完成渲染组件,而任何获取请求都在后台进行。由于您的 React Query 尚未返回任何内容,因此在组件第一次渲染时,您为查询数据设置的变量仍未定义。

React Query 有一个附加到查询对象的 isFetched 方法。您可以使用条件仅在数据已获取时继续。

if(data.isFetched){
  console.log(data)
} else {
  console.log("loading")
}
Cthuwu
2022-10-13