在 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 Native 和 useEffect 获取
使用动态路由、下一个 JS 和 useEffect 在 React 中获取数据