使用 axios 进行异步 API 调用后出现 TypeError
2021-04-09
109
我试图弄清楚我的代码中发生的一些事情。 我正在从我创建的 Rest API 中获取一些数据,在异步调用之后我得到了:
TypeError:无法读取未定义的属性“field”
我无法弄清楚发生了什么,因为当我在控制台上记录数据时,我可以看到我的对象填充了正确的信息。为了确保我没有犯类型错误,我从
console.log(response)
复制了数据并创建了一个对象,并且它工作正常。
这是调用:
import axios from 'axios';
const url_service_villain = "https://some_url/"
export const findRandomVillain = async () => {
try {
const {data} = await axios.get(url_service_villain + "find/random");
return await data
} catch (err) {
console.log(err);
};
};
这是我调用方法的地方:
import React from 'react';
import Character from './components/Character'
import {findRandomVillain} from './services/VillainService';
async function getRandomVillain(){
const data = await findRandomVillain();
console.log(data);
return data;
}
function CharacterList(){
const char = getRandomVillain();
return (
<section className="characterList">
<Character key={char.id} images={char.images.md} name={char.name} powerstats={char.powerstats}/>
</section>
)
};
export default CharacterList;
在方法
getRandomVillain()
上,
console.log(data)
打印我想要的对象,
但在
CharacterList
上,我得到了上面列出的
TypeError
。
我还注意到控制台窗口顶部有以下内容:
Promise {<pending>} App.js:17
Promise {<pending>} App.js:17
App.js:20 Uncaught TypeError: Cannot read property 'md' of undefined
at CharacterList (App.js:20)
...{/*long list of errors here*/}
{id: "123", name: "Sinestro", powerstats: {…}, images: {…}} App.js:11
{id: "123", name: "Sinestro", powerstats: {…}, images: {…}} App.js:11
{id: "123", name: "Sinestro", powerstats: {…}, images: {…}} App.js:11
我认为这与异步调用有关,我不知道为什么最后一行重复 3 次,因为我只是记录它一次。
2个回答
当 React 组件正在渲染时。它不会等待异步调用完成。当 React 组件首次挂载时,char 为空,但您从 char: "id"; "name" 获取属性值。因此,您需要添加一个异常,以确保何时使用 char 渲染组件角色并成功调用 API。
{char !== undefined (exceptions here) && }
Tommy Tang
2021-04-09
您需要使用
then()、catch()
处理承诺,以
阅读更多
解决方案是在组件准备就绪时通过使用
useEffect
调用
findRandomVillain()
,并使用
useState
设置
char
import React, { useEffect, useState } from "react";
import Character from "./components/Character";
import { findRandomVillain } from "./services/VillainService";
function CharacterList() {
const [char, setChar] = useState();
// using useEffect to make sure component is Ready
useEffect(() => {
findRandomVillain()
.then((res) => setChar(res)) // handle promising
.catch((err) => console.log(err));
}, []);
if (!char) return <div>loading</div>;
return (
<section className="characterList">
<Character
key={char.id}
images={char.images.md}
name={char.name}
powerstats={char.powerstats}
/>
</section>
);
}
export default CharacterList;
Mohamed Ahmed
2021-04-09