我是 React js 的新手,为了练习我的技能,我尝试使用 pokemon api 制作一个 pokemon react js 应用程序。遵循教程后,我决定在应用程序中添加更多功能以供进一步练习。
我想要做的是使用useState
钩子和onClick
函数在单击按钮时更改获取的 url 。当我将resourceType
to更改为berry
from 时pokemon
,它会成功更新,但是问题是当我尝试pokemon
从berry
state 未更新到pokemon
.
我不确定为什么会发生这种情况,因为在useEffect
函数中,我已经包含了对 的依赖resourceType
,因此每次resourceType
更新时它都应该改变。
任何指向正确方向的提示将不胜感激。
主要App.js
成分:
import './App.css';
import { Button } from '@material-ui/core'
import React, { useEffect, useState } from 'react'
import BerryCards from './Components/BerryCards';
import PokemonCards from './Components/PokemonCards';
function App() {
const [resourceType, setResourceType] = useState('pokemon');
const [data, setData] = useState([]);
const [nextUrl, setNextUrl] = useState('');
const [prevUrl, setPrevUrl] = useState('');
const [loading, setLoading] = useState(true);
async function getAllPokemon(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(res => res.json())
.then(data => {
resolve(data);
})
})
}
async function getPokemons(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(res => res.json())
.then(data => {
resolve(data);
})
})
}
useEffect(() => {
async function fetchData() {
try {
let response = await getAllPokemon(`https://pokeapi.co/api/v2/${resourceType}`);
setNextUrl(response.next)
setPrevUrl(response.previous)
setLoading(false)
await loadingPokemon(response.results);
}
catch (e) {
console.log(e);
}
}
fetchData();
}, [resourceType])
console.log(resourceType)
const next = async () => {
setLoading(true)
let nextData = await getAllPokemon(nextUrl)
await loadingPokemon(nextData.results)
setNextUrl(nextData.next)
setPrevUrl(nextData.previous)
setLoading(false)
}
const prev = async () => {
if (!prevUrl) {
return;
} else {
setLoading(true)
let nextData = await getAllPokemon(prevUrl)
await loadingPokemon(nextData.results)
setNextUrl(nextData.next)
setPrevUrl(nextData.previous)
setLoading(false)
}
}
const loadingPokemon = async (pokemonData) => {
let _pokemon = await Promise.all(pokemonData.map(async pokemon => {
let pokemonRecord = await getPokemons(pokemon.url);
return pokemonRecord;
}))
setData(_pokemon)
}
return (
<div>
{loading ? <h1>Loading...</h1> : (
<>
<div>
<div>
<Button onClick={() => setResourceType('berry')}>Berries</Button>
<Button onClick={() => setResourceType('pokemon')}>Pokemon</Button>
</div>
<div>
{!prevUrl ? <Button onClick={prev} variant="outlined" disabled>Prev</Button> :
<Button onClick={prev} variant="outlined" color="primary">Prev</Button>}
{!nextUrl ? <Button onClick={next} disabled variant="outlined">Next</Button> :
<Button onClick={next} color="primary" variant="outlined">Next</Button>}
</div>
{resourceType === 'pokemon' ? data && data.map((pokemon, i) => {
return (
<div>
<PokemonCards key={i}
pokemon={pokemon} />
</div>
)
}) : data && data.map((berry, i) => {
return (
<div>
<BerryCards key={i}
berry={berry} />
</div>
)
})}
</div >
</>
)
}
</div >
)
}
export default App;
使用 props 将数据传递给其他 UI 组件
import React from 'react'
import { Card } from '@material-ui/core'
const BerryCards = ({ berry }) => {
return (
<div>
<Card>
<p>{berry.name}</p>
<p>{berry.natural_gift_power}</p>
</Card>
</div>
)
}
export default BerryCards
import React from 'react'
import { Card } from '@material-ui/core'
const PokemonCards = ({ pokemon }) => {
try {
return (
<div>
<Card>
<p>{pokemon.name}</p>
{pokemon.types.map(type => <p key={Math.random() + 1}>{type.type.name}</p>)}
<p>Height {pokemon.height}</p>
<p>Weight {pokemon.weight}</p>
<p>Ability: {pokemon.abilities[0].ability.name}</p>
<img src={pokemon.sprites.front_default} alt={pokemon.name}></img>
</Card>
</div>
)
} catch (e) {
console.log(e)
//the problem- when request url is changed to berries, it remains as berries and is not changed
console.log(pokemon)
}
}
export default PokemonCards
您当前的代码抛出错误 bcz 您没有返回任何要渲染的元素。只需在catch语句中添加以下代码
} catch (e) {
return null;
}
您也可以try & catch
像这样在代码中完全删除和添加空检查:
const PokemonCards = ({ pokemon }) => {
return (
<div>
<Card>
<p>{pokemon.name}</p>
{pokemon.types && pokemon.types.map(type => <p key={Math.random() + 1}>{type.type.name}</p>)}
<p>Height {pokemon.height}</p>
<p>Weight {pokemon.weight}</p>
<p>Ability: {pokemon.abilities && pokemon.abilities[0].ability.name}</p>
<img src={pokemon.sprites && pokemon.sprites.front_default} alt={pokemon.name}></img>
</Card>
</div>
)
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句