React+TypeScript如何解决Source has 1 element(s) but target allows only 0错误
报错原因
- TypeScript 会对未显式指定类型的 useState 初始值做自动类型推断,你初始化
pokemon状态时传入空数组[],TS 默认将其类型推断为长度为0的空数组,不允许后续往数组内添加任何元素,因此调用setPokemon追加数据时触发类型不匹配报错。 - 代码还存在两处逻辑错误:一是 fetch 接口返回的 Response 对象没有
data属性,你已经通过await response.json()拿到响应数据赋值给data变量,直接使用data访问字段即可;二是 API 地址拼写错误,缺少//,会导致请求失败。 - 多余的错误赋值逻辑:
setPokemon(response.data.results[0].name)这行直接将字符串赋值给数组类型的pokemon状态,本身也不符合类型要求。
修复步骤
- 给 useState 显式指定泛型类型,明确
pokemon是PokemonItem类型的数组:
const [pokemon, setPokemon] = React.useState<PokemonItem[]>([]);
- 删除错误的字符串赋值代码
setPokemon(response.data.results[0].name)。 - 修正所有 API 地址的拼写,将
https:替换为https://。 - 把
response.data.results替换为data.results。 - (可选优化)forEach 包裹的异步请求返回顺序不可控,且会触发多次状态更新,建议使用
Promise.all批量获取所有宝可梦数据后一次性更新状态,减少不必要的渲染。
修复后完整代码
import React from 'react'; const API_URL = 'https://pokeapi.co/api/v2/pokemon'; export interface PokemonItem { id: number; name: string; height: string; weight: string; abilities: string; } interface Props { pokemonItem: PokemonItem[]; children: React.ReactNode | React.ReactNode[]; } export const PokemonContainer: React.FC<Props> = (props) => { const [pokemon, setPokemon] = React.useState<PokemonItem[]>([]); const [loadItems, setLoadItems] = React.useState(API_URL); const getPokemons = async () => { const response = await fetch(loadItems); const data = await response.json(); setLoadItems(data.next); console.log(data.results); // 批量请求所有宝可梦数据 const pokemonRequests = data.results.map(async (element: {name: string}) => { const res = await fetch( `https://pokeapi.co/api/v2/pokemon/${element.name}` ); return await res.json() as PokemonItem; }); const pokemonList = await Promise.all(pokemonRequests); setPokemon(prev => [...prev, ...pokemonList]); console.log(pokemonList); }; React.useEffect(() => { getPokemons(); }, []); // 这里补全组件返回逻辑即可 return <>{props.children}</> };
内容的提问来源于stack exchange,提问作者Waiz
相关产品推荐
相关产品推荐

