在 React 的 useEffect() 中获取数据返回“undefined”

IT技术 javascript reactjs promise use-effect react-functional-component
2021-05-16 00:09:32

我正在尝试从数据库中获取数据。这是一个获取请求。只要我在异步函数中使用获取的数据,一切都可以正常工作。但除此之外,它只返回“未定义”。我究竟做错了什么?谢谢你的帮助 :)

const [accountInfos, setAccountInfos] = useState();
      const [error, setError] = useState();
      const [loading, setLoading] = useState(true);

      useEffect(() => {
        (async function runEffect() {
            const fetchedAccountInfos =  await fetchAccountInfos();
            if (fetchedAccountInfos && fetchedAccountInfos.length > 0) {
                console.log(fetchedAccountInfos)  //This console.log works
                setAccountInfos(fetchedAccountInfos);
                setLoading(false);
                console.log(accountInfos)  //This console.log returns 
                                             "undefined"
              } else {
                setError("Accountdaten können nicht geladen werden!");
                setLoading(false);
                };
        })();
      }, []);
      console.log(accountInfos);  //This console.log returns "undefined"
4个回答

它不是特定于 React 的:这是一个异步函数,所以Promise将在控制台日志发生后解决,这就是为什么你得到undefined. 这只是正常的 JS 行为——在console.log 执行时该值未定义的。

在定义 JSX 的返回值中,如果accountinfos为 null,则渲染null(或某个空状态组件),否则根据 API 的返回值渲染实际组件。收到响应后,状态将更新,组件将重新渲染

您没有做错任何事情,useEffect 外部的 console.log 仅在初始组件函数调用时执行一次,因此当时 accountInfos 变量仍未定义。

但是useEffect里面的console.log是在获取数据后执行的,所以是在那个时候定义的。

试试这个只是为了看看结果?

      const [accountInfos, setAccountInfos] = useState();
      const [error, setError] = useState();
      const [loading, setLoading] = useState(true);

      useEffect(() => {
        (async function runEffect() {
            const fetchedAccountInfos =  await fetchAccountInfos();
            if (fetchedAccountInfos && fetchedAccountInfos.length > 0) {
                setAccountInfos(fetchedAccountInfos);
                setLoading(false);
                console.log(accountInfos)  //This console.log works
              } else {
                setError("Accountdaten können nicht geladen werden!");
                setLoading(false);
                };
        })();
      }, []);
      console.log(accountInfos);  //This console.log returns "undefined"

      useEffect(() => {
        console.log(accountInfos); //check the result here
      }, [accountInfos])

由于大多数答案已经说明了其引起的问题,即 JS 的异步性质。解决这个问题的解决方案是简单地使用条件语句或三元运算符。

const [accountInfos, setAccountInfos] = useState();
  const [error, setError] = useState();
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    (async function runEffect() {
        const fetchedAccountInfos =  await fetchAccountInfos();
        if (fetchedAccountInfos && fetchedAccountInfos.length > 0) {
            console.log(fetchedAccountInfos)  //This console.log works
            setAccountInfos(fetchedAccountInfos);
            setLoading(false);
            if(accountInfos){
                //console the output only if available
                 console.log(accountInfos);
            }
          } else {
            setError("Accountdaten können nicht geladen werden!");
            setLoading(false);
            };
    })();
  }, []);
  console.log(accountInfos);  //This console.log returns "undefined"

如果渲染组件并在 useEffect 挂钩中获取一些数据,则相同的方法很有用。

{
   dataIsReturned ? <RenderYourData/> : <h1> Loading </h1>
}