在 React 的 useEffect() 中获取数据返回“未定义”

Posted

技术标签:

【中文标题】在 React 的 useEffect() 中获取数据返回“未定义”【英文标题】:Fetching data in React's useEffect() returns "undefined" 【发布时间】:2020-03-15 00:11:27 【问题描述】:

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

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"

【问题讨论】:

accountInfos 是异步设置的,因此您不能指望它稍后再设置(在您 await 获取数据的范围之外)。您的代码需要测试数据是否存在。 【参考方案1】:

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

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

【讨论】:

【参考方案2】:

你没有做错什么,useEffect 之外的 console.log 只是在初始组件函数调用上执行一次,所以当时 accountInfos 变量仍然未定义。

不过useEffect里面的console.log是在获取数据后执行的,所以是当时定义的。

【讨论】:

【参考方案3】:

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

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

【讨论】:

但还是尝试了你的建议。首先它还返回“未定义”,然后它返回正确的对象。所以它会触发两次 但我现在真的不知道如何处理这些信息。 您从该获取中获得的数据可能会显示在 JSX 中的某个位置,该位置位于 return();所以你在那里不会遇到任何问题。至于你的情况,我认为 Daniel Herrero Hernando 给了你正确的答案。【参考方案4】:

由于大多数答案已经说明了问题的原因,即 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>

【讨论】:

【参考方案5】:

为了获取更新后的值,然后根据该值执行一些操作,您需要使用useEffect 挂钩

例如

const [toggle, setToggle] = useState(false);

useEffect(() => 
   // do something based on new value of toggle
, [toggle]);

const trigger = () => 
  setToggle(true);
  // OR
  //setToggle(t => !t);

【讨论】:

这个问题实际上是关于在useEffect 中获取数据,它在问题标题中,代码在问题正文中。这是对不同问题的回答吗(您的回答似乎与这里的任何内容无关)?

以上是关于在 React 的 useEffect() 中获取数据返回“未定义”的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React 函数组件中不使用 useEffect 钩子获取数据?

React内部useEffect中使用fetch的问题

使用 React Native 和 useEffect 获取

使用动态路由、下一个 JS 和 useEffect 在 React 中获取数据

如何在 React 的 UseEffect() 中调用异步函数?

使用 `useEffect` 根据 React 状态切换递归获取请求