使用 useState 钩子单击按钮不会更新 reactjs 状态

sol_s

我是 React js 的新手,为了练习我的技能,我尝试使用 pokemon api 制作一个 pokemon react js 应用程序。遵循教程后,我决定在应用程序中添加更多功能以供进一步练习。

我想要做的是使用useState钩子和onClick函数在单击按钮时更改获取的 url 当我将resourceTypeto更改berryfrom 时pokemon,它会成功更新,但是问题是当我尝试pokemonberrystate 未更新到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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用useState钩子未设置状态 ReactJS

如何使用useState钩子更新对象状态

使用useState通过单击按钮来反应更新状态

useState不会使用组件更新状态

React Hooks:使用useState更新状态不会立即更新状态

使用React useState()钩子更新和合并状态对象

如何使用useState钩子一次更新多个状态?

React钩子:如何使用useState()更新嵌套对象上的状态?

无法在 reactjs 中使用 useState 设置状态数据

ReactJS - 使用 useState 钩子维护数值

如何使用useState钩更新状态

React js useState 钩子。单击复选框时如何使用其中的数组更新 json 对象的状态

react js无法使用useState更新按钮状态

使用 useState 传播状态

在 Reactjs 中使用 UseState

foreach 循环无法使用状态钩子 reactjs

UseState,UseEffect不更新reactjs中的状态。我正在尝试向状态添加随机数

如何更新 useState 钩子中的反应状态?

使用 useState 钩子更改状态后,React JS 代码不会重新渲染

与 TypeScript 反应:如何使用先前的状态键入 useState 钩子

如何使用useState钩子和Typescript初始化状态

如何使用useState钩子同时设置多个状态?

使用React useState钩子设置多个状态值

使用初始状态反应useState钩子事件处理程序

使用 ReactJS 的 useState 钩子设置变量不起作用

使用钩子(useState)反应更新状态对象有效,但没有重新渲染

为什么使用钩子单击按钮后状态没有更新?

如何在ReactJs中使用Hooks useState编写多行状态

如何使用 ReactJS 镜像开关按钮的状态?