反应 useState 钩子不使用 axios 调用更新
Posted
技术标签:
【中文标题】反应 useState 钩子不使用 axios 调用更新【英文标题】:React useState hook not updating with axios call 【发布时间】:2021-10-20 04:18:58 【问题描述】:我知道这是一个常见问题,因为我在过去的两个小时里都在检查每个答案并试图更新我的状态,但没有任何效果。
我正在从 cms 获取文本,但是在第一次加载时状态未定义并且我的应用程序崩溃了。但是,如果我注释掉该行,加载页面并取消注释该行会显示正确的值。
这是我尝试过的一些代码。
我希望得到的数据
[
id:1,
id:2,
id:3,
id:4,
]
import react, useEffect, useState from 'react'
import axios from 'axios'
const [carouselTitle, setCarouselTitle] = useState([])
useEffect(() =>
fetchData();
, []);
const fetchData = async () =>
await axios('api').then(
response =>
console.log(response.data)
setCarouselTitle(response.data)
console.log(carouselTitle)
)
;
return(
<h1>carouselTitle[1].id</h1>
)
控制台记录数据工作正常,但是当我控制台记录状态时它不起作用。
我尝试的第二种方法
useEffect(() =>
const fetchData = async () =>
const res = await axios('api');
const carouselTitleAlt = await res.data;
setCarouselTitle( carouselTitleAlt );
console.log(carouselTitleAlt);
console.log(carouselTitle);
;
fetchData();
, []);
再次控制台记录 useEffect 中的 const 会显示正确的信息,但记录状态不起作用。
感谢您的回复或显示数据的更好方式。
【问题讨论】:
你在 useEffect 之外尝试过console.log(carouselTitle)
吗?
const [carouselTitle, setCarouselTitle] = useState([]
- 这是一个错字吗?缺少正确的括号?
@selbie 是的,抱歉,这是一个 *** 错字可以确认我的代码有正确的括号!好地方寿:)
@matt_roki2 的回答对你有帮助吗?
【参考方案1】:
setState
是异步的:https://reactjs.org/docs/faq-state.html#why-doesnt-react-update-thisstate-synchronously
这意味着您不能期望在调用setCarouselTitle
之后的行中控制台记录新的状态值。
要记录新值,您可以使用另一个 useEffect,在依赖项数组中使用 carouselTitle,您可以在其中 console.log(carouselTitle)
:
useEffect(() =>
console.log(carouselTitle);
, [carouselTitle]);
也就是说,你的组件应该正确运行,当状态更新时它会被刷新。
在 JSX 中,您应该检查 carouselTitle 是否未定义(意味着请求失败或仍在等待中):
carouselTitle && <H1>carouselTitle[0].id
https://reactjs.org/docs/conditional-rendering.html#gatsby-focus-wrapper
【讨论】:
感谢您的回答。是的,这确实 console.log 它但仍然导致应用程序在页面刷新时以cannot read property of id
崩溃。如果它是状态更新,它可以工作,但仍然会遇到同样的问题...... :(
好的,具体的错误是什么?无法读取未定义的属性 ID?您如何尝试使用您获取的数据?
抱歉没有在您的回答中看到 JSX!
您应该在使用前检查 carouselTitle:carouselTitle && carouselTitle[1].id。编辑了我的答案。
和我问丹尼尔的问题一样,为什么会这样?【参考方案2】:
首先,如果将初始数据的空数组传递给 useState,则无法在此处获取该数组中的任何项:
return(
<h1>carouselTitle[1].id</h1>
)
因为组件返回的数组的第一项没有任何内容。我更喜欢你这样做:
return(
<h1>carouselTitle.length > 0 && carouselTitle[0].id</h1>
)
并且还基于this 和official documentation,setState
(以及使用useState()
的setSomthing()
)是异步的。
所以状态数据在设置后不会立即显示。
【讨论】:
这已经解决了,谢谢,但是为什么呢?那行代码背后的逻辑是什么? 在您的版本中,您尝试访问一个未定义值的索引,直到请求返回。所以 javascript 会抛出一个错误。 @matt_roki2 正如我所说,您将一个空数组传递给useState
,在第一次渲染中,组件返回一个没有任何内容的数组的第一项【参考方案3】:
你应该触发 useEffect 来运行 fetch 函数
useEffect(()=>fetchData();,[carouselTitle])
【讨论】:
以上是关于反应 useState 钩子不使用 axios 调用更新的主要内容,如果未能解决你的问题,请参考以下文章