React中useEffect获取API数据并渲染失败问题求助
问题分析与解决方案
核心问题
你的代码存在两个关键问题,导致selectData始终为null,页面持续显示Loading...:
- 异步时序错误:
get是异步函数,调用get()后立刻执行data.forEach时,axios请求还未完成,data仍为初始空数组,无法找到id为1的元素。 - useEffect依赖缺失:即便后续
data通过setData更新,由于第一个useEffect的依赖数组为空,它不会重新执行,也就不会再次遍历data设置selectData。
修复方案(两种可选)
方案一:请求成功后直接处理目标数据
在get函数中拿到返回数据后,同时设置data和selectData,无需等待组件重新渲染:
import React from "react"; import axios from "axios"; export const Teste = () => { const [data, setData] = React.useState([]); const [selectData, setSelectData] = React.useState(null); const get = async () => { try { const response = await axios.get("http://localhost:5000/posts"); const posts = response.data; setData(posts); // 直接定位id为1的帖子并设置 const targetPost = posts.find(post => post.id === 1); if (targetPost) { setSelectData(targetPost); } } catch (err) { console.log(err); } }; React.useEffect(() => { get(); }, []); return ( <section> {selectData !== null ? ( <div> <h1>{selectData.title}</h1> <div> <p>{selectData.text}</p> </div> <button>Atualizar</button> </div> ) : ( "Loading..." )} </section> ); };
方案二:监听data变化,单独处理selectData
保留原有get函数,新增一个依赖data的useEffect,当data更新时自动查找并设置目标数据:
import React from "react"; import axios from "axios"; export const Teste = () => { const [data, setData] = React.useState([]); const [selectData, setSelectData] = React.useState(null); const get = async () => { await axios .get("http://localhost:5000/posts") .then((response) => setData(response.data)) .catch((err) => console.log(err)); }; React.useEffect(() => { get(); }, []); // 当data更新时,自动查找并设置目标数据 React.useEffect(() => { if (data.length > 0) { const targetPost = data.find(post => post.id === 1); if (targetPost) { setSelectData(targetPost); } } }, [data]); return ( <section> {selectData !== null ? ( <div> <h1>{selectData.title}</h1> <div> <p>{selectData.text}</p> </div> <button>Atualizar</button> </div> ) : ( "Loading..." )} </section> ); };
额外优化提示
- 用
find替代forEach更高效,find找到目标元素后会直接返回,无需遍历整个数组。 - 异步函数中尽量统一使用
try/catch或.catch写法,避免混合使用(方案一的try/catch比原代码的await + .then/.catch更清晰)。
内容的提问来源于stack exchange,提问作者Lucas Santana Figueiredo
相关产品推荐
相关产品推荐

