React中useState无法设置Axios请求返回值的问题排查
问题:GET请求返回数据正常,但useState无法更新状态
尝试向http://localhost:8080/api/RE/template/${pageId}发送GET请求获取对应pageId的模板项,控制台能看到请求返回的数据,但setLoadedTemplates无法更新loadedTemplates状态。
相关代码(TemplateRealEstate.js)
const TemplateRealEstate = () => { const [loadedTemplates, setLoadedTemplates] = useState([]) const pageId = useParams().pageId; const getTemplates = async () => { await axios({ method: "GET", url: `http://localhost:8080/api/RE/template/${pageId}`, headers: "Content-type: application/json" }) .then((res) => { console.log("Respond from the request -->", res) setTimeout(() => setLoadedTemplates(res.data.templates), 0); console.log("Res.data.templates -->", res.data.templates) }) .catch((err) => { console.log(err) }) console.log("Loaded Templates --> ", loadedTemplates) } useEffect(() => { getTemplates(); }, [pageId]) }
已尝试的方案
- 使用
useCallback、setTimeout - 将
loadedTemplates加入useEffect依赖导致页面无限渲染 - 修改GET请求的Content-Type请求头(尝试
application/json和multipart/form-data) - 留空
useEffect依赖也无法解决问题 - 其他GET请求无此问题
问题原因及解决办法
核心原因
- 状态更新的异步特性:
setState是异步操作,你在getTemplates末尾打印loadedTemplates时,状态还未完成更新,所以看到的是旧值,但实际上状态可能已经更新了,只是你没在正确的时机查看。 - Axios请求头格式错误:headers参数应该是对象格式
{ "Content-Type": "application/json" },而非字符串"Content-type: application/json",虽然GET请求通常不需要这个头,但格式错误可能引发潜在问题。 - 混合使用async/await与then/catch:同时使用两种异步处理方式会导致逻辑混乱,可能隐藏执行顺序的问题。
解决步骤
修正请求头格式
将headers改为对象格式,甚至可以直接省略(GET请求Axios默认会处理):headers: { "Content-Type": "application/json" }统一异步处理方式
选择async/await + try/catch或者.then/.catch的其中一种,不要混合使用,示例如下:const getTemplates = async () => { try { const res = await axios({ method: "GET", url: `http://localhost:8080/api/RE/template/${pageId}` }); console.log("Respond from the request -->", res); console.log("Res.data.templates -->", res.data.templates); setLoadedTemplates(res.data.templates); } catch (err) { console.log(err); } };正确查看状态更新结果
不要在setLoadedTemplates后立即打印状态,而是通过useEffect监听状态变化:useEffect(() => { console.log("Updated Loaded Templates --> ", loadedTemplates); }, [loadedTemplates]);或者直接在组件渲染部分输出
loadedTemplates,确认状态是否更新。移除不必要的setTimeout
在请求回调中执行setLoadedTemplates本身就是异步任务,不需要额外用setTimeout包裹,反而可能引入不必要的延迟。
内容的提问来源于stack exchange,提问作者yuroni
相关产品推荐
相关产品推荐

