【发布时间】:2021-08-10 02:31:33
【问题描述】:
我是 React js 的新手,为了练习我的技能,我尝试使用 pokemon api 制作一个 pokemon react js 应用程序。在学习完教程后,我决定在应用程序中添加更多功能以供进一步练习。
我想要做的是使用useState 钩子和onClick 函数在单击按钮时更改获取的url。当我将resourceType 从pokemon 更改为berry 时,它更新成功,但是问题是当我尝试从berry 查询pokemon 时,状态未更新为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
【问题讨论】:
-
>但是问题是当我尝试从
berry查询pokemon你的意思是当你点击pokemon按钮时? -
@CVerica 是的,很抱歉没有澄清 - 所以最初当状态为“口袋妖怪”时,它成功地从查询中加载数据,但是当我点击 berry 后点击口袋妖怪按钮时,状态不会'不改变并保持为'浆果'
标签: javascript reactjs use-state