React使用map访问对象数据、点击按钮展示宝可梦名称的问题
问题根源
你现有代码存在5个核心问题,导致无法实现需求:
- 接口请求函数
getPokemon仅在控制台打印返回结果,没有将请求到的宝可梦数据对外返回 - 组件内没有定义响应式状态存储接口数据,React无法感知数据变化触发页面重渲染
- 类型定义错误:PokeAPI返回的
results数组项不是字符串类型,是包含name、url字段的对象 - 存在冗余导入:
pokeAPI.ts是纯请求逻辑文件,不需要导入React - 页面结构中没有预留数据渲染的位置,拿到数据也无处展示
修正后完整代码
pokeAPI.ts(请求逻辑文件)
import axios from 'axios' // 定义宝可梦列表项的TS类型,提前规避类型错误 interface PokemonItem { name: string; url: string; } // 函数返回Promise,将拉取到的结果对外暴露给组件调用 export const getPokemon = async () => { const response = await axios.get("https://pokeapi.co/api/v2/pokemon?limit=151"); return response.data.results as PokemonItem[]; }
App.tsx(页面组件文件)
import './App.css'; import React, { useState } from 'react'; import { getPokemon } from './func/pokeAPI'; function App() { // 定义响应式状态存储宝可梦列表,初始值为空数组 const [pokemonList, setPokemonList] = useState<PokemonItem[]>([]); // 定义加载状态,避免用户重复点击触发冗余请求 const [loading, setLoading] = useState(false); // 按钮点击触发的请求处理逻辑 const handleClick = async () => { if (loading) return; setLoading(true); try { const list = await getPokemon(); // 将接口返回数据存入状态,React会自动触发页面重渲染 setPokemonList(list); } catch (err) { console.error('获取宝可梦数据失败:', err); } finally { setLoading(false); } } return ( <div> <button onClick={handleClick} disabled={loading}> {loading ? '加载中...' : '获取宝可梦列表'} </button> {/* 遍历状态中的列表,渲染每个宝可梦的name字段 */} <ul style={{ marginTop: '16px' }}> {pokemonList.map((item, index) => ( <li key={index}>{item.name}</li> ))} </ul> </div> ); } export default App;
实现逻辑说明
这套逻辑是React请求接口渲染数据的通用范式,可以直接复用到同类需求中:
- 逻辑分层:接口请求函数只负责拉取数据、做基础类型转换,不掺杂打印、DOM操作这类UI逻辑,复用性更强
- 状态驱动视图:React是状态驱动的框架,所有需要渲染到页面的可变数据,都必须存在
useState这类响应式状态中,状态更新后框架会自动完成页面重绘,不需要手动操作DOM - 异步处理:用
async/await语法处理axios的异步请求,比链式then调用可读性更高,同时搭配loading状态优化交互、避免重复请求 - 列表渲染规范:遍历数组生成DOM节点时,要给每个节点设置唯一key值,生产环境建议用接口返回的唯一ID代替数组索引,减少渲染bug
- 类型约束:提前用TS定义接口返回值结构,开发阶段就能发现字段名写错、类型不匹配这类低级错误
内容的提问来源于stack exchange,提问作者MikeyNeedHelp
相关产品推荐
相关产品推荐

