React调用StarWars API报错:Cannot read properties of undefined (reading 'map')
React调用API报错:Cannot read properties of undefined (reading 'map')
我正在学习用React调用API,代码运行时控制台报错:Uncaught TypeError: Cannot read properties of undefined (reading 'map'),位置在App.jsx第24行。已经用了可选链操作符,但问题还是没解决,附上代码求帮助。
代码文件
useFetch.js
import axios from "axios" import { useEffect, useState } from "react" const useFetch = url => { const [response, setResponse] = useState() useEffect( () => { axios.get(url) .then(res=>setResponse(res.data)) .catch(err=> console.log(err.message)) }, []) return response } export default useFetch
App.jsx
import axios from 'axios' import { useEffect, useState } from 'react' import './App.css' import FormInput from './components/FormInput' import Residents from './components/Residents' function App() { const [planets, setPlanets] = useState() const [response, setResponse] = useState() const number = parseInt(response) const updatePage = number => { const URL = `https://swapi.dev/api/planets/${number}/` axios.get(URL) .then(res => setPlanets(res.data)) .catch(err => console.log(err.message)) } useEffect(() => { const URL = `https://swapi.dev/api/planets/${number}/` axios.get(URL) .then(res => updatePage()) .catch(err => console.log(err.message)) }, []) console.log(number) return ( <div className="App"> <FormInput setResponse={setResponse} /> <hr /> { planets?.residents.map(resident => ( <Residents resident={resident} key={resident.name} /> )) } </div> ) } export default App
Residents.jsx
import React from 'react' import useFetch from '../hooks/useFetch' const Residents = ({ resident }) => { const users = useFetch(resident) console.log(users) return ( <article> </article> ) } export default Residents
问题分析与修复
1. 核心报错修复
你用了planets?.residents.map,但当planets存在但residents为undefined(比如API请求失败、数据未加载完成)时,undefined.map依然会触发报错。需要给residents也加上可选链;另外SWAPI返回的resident是URL字符串,不是对象,key={resident.name}会报错,改用URL作为唯一key:
{planets?.residents?.map(resident => ( <Residents resident={resident} key={resident} /> ))}
2. 初始化逻辑修正
response初始值为undefined,parseInt(response)得到NaN,导致初始请求URL无效,给response设置默认值:const [response, setResponse] = useState("1")- 原初始
useEffect调用updatePage()未传参数,且未监听number变化,用户输入新数字后无法触发更新,替换为监听number变化的逻辑:useEffect(() => { if (!isNaN(number)) { updatePage(number) } }, [number])
3. useFetch钩子优化
给response设置初始状态为null避免返回undefined,同时添加url作为依赖,确保URL变化时重新请求:
const [response, setResponse] = useState(null) useEffect(() => { axios.get(url) .then(res => setResponse(res.data)) .catch(err => console.log(err.message)) }, [url])
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

