React中使用useEffect触发API请求问题:点击按钮无法获取新宝可梦
解决随机宝可梦生成器的点击无响应问题
问题根源
- 状态类型混乱:初始
pokemon状态存的是数字ID,但后续请求后又把它改成了宝可梦对象,点击按钮时再把数字ID赋值给它,导致pokemon?.name无法读取属性,页面显示为空。 - useEffect未监听状态变化:依赖数组为空,仅在组件首次挂载时执行一次请求,点击按钮不会触发新的请求。
- 按钮逻辑错误:直接将ID赋值给状态,没有触发请求流程。
修正后的代码
import './App.css'; import { useState, useEffect } from 'react'; // 生成随机宝可梦ID(API支持的ID范围是1-1011) function getNewPokemonId() { return Math.floor(Math.random() * 1011) + 1; // +1确保不会生成0 } function App() { // 拆分状态:一个存ID,一个存请求回来的宝可梦数据 const [pokemonId, setPokemonId] = useState(getNewPokemonId()); const [pokemonData, setPokemonData] = useState(null); // 当pokemonId变化时,自动发起请求 useEffect(() => { fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonId}`) .then((response) => response.json()) .then((data) => setPokemonData(data)) .catch((err) => console.error('请求失败:', err)); }, [pokemonId]); // 依赖pokemonId,ID变化就重新执行 return ( <main> <h1>Random Pokemon Generator</h1> <section> {/* 点击按钮只更新ID,触发useEffect发起新请求 */} <button onClick={() => setPokemonId(getNewPokemonId())}> New Pokemon </button> {/* 数据加载完成前显示提示,避免页面为空 */} <h3>{pokemonData ? pokemonData.name : '加载中...'}</h3> </section> </main> ); } export default App;
关键改进点
- 拆分状态后,
pokemonId负责触发请求,pokemonData负责存储和展示数据,类型清晰。 useEffect依赖pokemonId,每次点击按钮更新ID时,都会自动发起新的请求。- 增加了加载状态提示,避免数据未返回时页面为空。
内容的提问来源于stack exchange,提问作者Taha Kamran
相关产品推荐
相关产品推荐

