尝试使用 API 创建口袋妖怪搜索,但遇到数据未按时加载的问题
Posted
技术标签:
【中文标题】尝试使用 API 创建口袋妖怪搜索,但遇到数据未按时加载的问题【英文标题】:Trying to create a pokemon search using API but running into issue where data is not being loaded on time 【发布时间】:2021-06-11 15:11:11 【问题描述】:我正在尝试在这里使用 pokemon api 创建一个 pokemon 搜索应用程序 - https://pokeapi.co/ 我收到“无法读取未定义的属性‘物种’”的错误。 这是我应该使用useEffect的地方吗? 我猜这与我没有使用 async / await 功能有关,但我想先问一下它是否可能是别的东西。
这是我的代码
import useState, useEffect from "react";
import "./App.css";
function App()
const [pokemonName, setPokemonName] = useState("ditto");
const [chosen, setChosen] = useState(false);
const [pokemonData, setPokemonData] = useState(
name: "",
species: "",
img: "",
hp: "",
attack: "",
defense: "",
type: "",
);
const searchPokemon = () =>
const response = fetch(
`https://pokeapi.co/api/v2/pokemon/$pokemonName`
).then((response) =>
setPokemonData(
name: pokemonName,
species: response.data.species.name,
img: response.data.sprites.front_default,
hp: response.data.stats[0].base.stat,
attack: response.data.stats[1].base.stat,
defense: response.data.stats[3].base.stat,
type: response.data.types[0].type.name,
);
setChosen(true);
);
console.log(response);
;
return (
<div className="App">
<input
className="border-b-2 border-black px-4"
type="text"
onChange=(e) =>
setPokemonName(e.target.value);
/>
<button
className="rounded text-white bg-blue-500 p-2 text-sm"
onClick=searchPokemon
>
Search Pokemon
</button>
<div>
!chosen ? (
<h1>Please choose a pokemon</h1>
) : (
<>
<h1>pokemonData.name</h1>
<img src=pokemonData.img alt=pokemonData.name />
<h2>pokemonData.species</h2>
<h2>pokemonData.type</h2>
<h2>pokemonData.hp</h2>
<h2>pokemonData.attack</h2>
<h2>pokemonData.defense</h2>
</>
)
</div>
</div>
);
export default App;
【问题讨论】:
***.com/questions/14220321/… 对 react 不太熟悉,但您可能应该使用useEffect
在数据加载后更改 DOM 值。
哪一行会引发错误?
【参考方案1】:
你忘记在获取后做 response.json() 以获取 json 格式的正文,并且数据形状有一些错误(响应不在“数据”属性下)
在这里查看修改后的工作版本:https://codesandbox.io/s/keen-***-8egfe?file=/src/App.js
【讨论】:
【参考方案2】:您没有将响应转换为.json()
,并且在解析响应时还添加了.data
,这不是必需的。另外,你base.stat
应该是base_state
。
const useState, useEffect = React;
function App()
const [pokemonName, setPokemonName] = useState("ditto");
const [chosen, setChosen] = useState(false);
const [pokemonData, setPokemonData] = useState(
name: "",
species: "",
img: "",
hp: "",
attack: "",
defense: "",
type: "",
);
const searchPokemon = () =>
const response = fetch(
`https://pokeapi.co/api/v2/pokemon/$pokemonName`
)
.then(response => response.json())
.then(response =>
setPokemonData(
name: pokemonName,
species: response.species.name,
img: response.sprites.front_default,
hp: response.stats[0].base_stat,
attack: response.stats[1].base_stat,
defense: response.stats[3].base_stat,
type: response.types[0].type.name,
);
setChosen(true);
);
;
return (
<div className="App">
<input
className="border-b-2 border-black px-4"
type="text"
onChange=(e) =>
setPokemonName(e.target.value);
/>
<button
className="rounded text-white bg-blue-500 p-2 text-sm"
onClick=searchPokemon
>
Search Pokemon
</button>
<div>
!chosen ? (
<h1>Please choose a pokemon</h1>
) : (
<React.Fragment>
<h1>pokemonData.name</h1>
<img src=pokemonData.img alt=pokemonData.name />
<h2>pokemonData.species</h2>
<h2>pokemonData.type</h2>
<h2>pokemonData.hp</h2>
<h2>pokemonData.attack</h2>
<h2>pokemonData.defense</h2>
</React.Fragment>
)
</div>
</div>
);
ReactDOM.render(
<App />,
root
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div id="root"></div>
【讨论】:
【参考方案3】:尝试创建一个函数来从 API 中获取数据。像这样的
function getPokemonData()
fetch('https://pokeapi.co/api/v2/pokemon/')
.then((response) => response.json())
.then((response) =>
setPokemonData(
name: pokemonName,
species: response.data.species.name,
img: response.data.sprites.front_default,
hp: response.data.stats[0].base.stat,
attack: response.data.stats[1].base.stat,
defense: response.data.stats[3].base.stat,
type: response.data.types[0].type.name,
)
);
然后在componentDidMount
里面调用这个函数componentDidMount()
this.getPokemonData();
【讨论】:
以上是关于尝试使用 API 创建口袋妖怪搜索,但遇到数据未按时加载的问题的主要内容,如果未能解决你的问题,请参考以下文章
如何解析这个 JSON 口袋妖怪字典?口袋妖怪 API (swift 3)