React中useEffect获取API数据后条件渲染报错的解决咨询
问题:React组件调用API后无法渲染数组,提示
map is not a function 我有一个React组件,核心功能是展示配置文件名称列表,数据存储在profiles这个useState变量中。组件通过useEffect调用API获取数据并存入profiles,当profiles长度为0时显示加载logo,否则遍历数组渲染为h1标签。虽然控制台日志显示已获取到数据,但始终报错:Uncaught TypeError: profiles.map is not a function。
原代码如下:
function ProfileListComponent() { const fetchProfiles = async (payload) => { const token = localStorage.getItem("token") const response = await axios.get("http://127.0.0.1:5000/profiles", {headers:{ "Authorization": `Bearer ${token}` }}) if (response.data) { let profileData = [] for (let key in response.data) { let profile = [ response.data[key].profile_id, response.data[key].profile_name, response.data[key].flow_rate, response.data[key].hv, response.data[key].lv, response.data[key].duty_cycle, response.data[key].frequency, ] profileData.push(profile) } console.log(profileData) return profileData } } const [profiles, setProfiles] = useState([]) const compileProfileData = () => { return "" } useEffect(() => { try { const profileData = fetchProfiles() setProfiles(profileData) } catch (error) { console.log(error) } }, []) return ( <div> {profiles.length === 0 ? <img src={logo} className="App-logo" alt="logo" /> : ( profiles.map(profile => <h1 className="profileBox" key={profile[0]} onClick={() => {compileProfileData(profile)}}>{profile[1]}</h1> ) )} </div> ) }
错误原因
- 异步函数返回Promise而非数组:
fetchProfiles是异步函数,直接调用fetchProfiles()会返回一个Promise对象,你直接将这个Promise赋值给了profiles状态,导致后续调用profiles.map()时,对象没有map方法,触发错误。 - 错误捕获无效:原代码中的
try/catch无法捕获异步函数的错误,因为没有用await等待异步操作完成。
修复方案
修改后的完整代码
function ProfileListComponent() { const fetchProfiles = async () => { try { const token = localStorage.getItem("token") const response = await axios.get("http://127.0.0.1:5000/profiles", { headers: { "Authorization": `Bearer ${token}` } }) if (response.data) { let profileData = [] for (let key in response.data) { let profile = [ response.data[key].profile_id, response.data[key].profile_name, response.data[key].flow_rate, response.data[key].hv, response.data[key].lv, response.data[key].duty_cycle, response.data[key].frequency, ] profileData.push(profile) } console.log(profileData) return profileData } return [] } catch (error) { console.log("获取配置文件失败:", error) return [] } } const [profiles, setProfiles] = useState([]) const compileProfileData = (profile) => { // 这里可添加处理选中配置文件的逻辑 console.log("选中的配置文件:", profile) } useEffect(() => { const loadProfiles = async () => { const profileData = await fetchProfiles() setProfiles(profileData) } loadProfiles() }, []) return ( <div> {profiles.length === 0 ? <img src={logo} className="App-logo" alt="logo" /> : ( profiles.map(profile => ( <h1 className="profileBox" key={profile[0]} onClick={() => compileProfileData(profile)} > {profile[1]} </h1> )) )} </div> ) }
关键修改点
- 在useEffect中定义异步函数
loadProfiles,用await等待fetchProfiles执行完成,获取真实数组后再更新状态。 - 将错误捕获逻辑移到
fetchProfiles内部,确保API请求失败时返回空数组,避免状态变为undefined。 - 给
compileProfileData添加参数,接收点击的profile数据,修复原函数无法获取选中项的问题。
内容的提问来源于stack exchange,提问作者ljohns
相关产品推荐
相关产品推荐

