You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中TypeError: weatherData.map is not a function问题求助

解决React遍历天气API数据时的TypeError问题

问题核心原因

你碰到的TypeError: weatherData.map is not a function和console.log(weatherData.response)输出undefined,本质是三个关键错误:

  • Axios响应结构误用:Axios请求返回的对象里,API实际数据存在data字段,而非response,你把整个Axios响应对象存进了状态,这个对象不是数组,自然用不了map。
  • API数据结构误解:OpenWeatherMap的/weather接口返回的是单个天气对象,不是数组,根本不需要用map遍历。
  • useEffect依赖逻辑错误:getWeatherData函数每次组件渲染都会重新创建,导致useEffect无限重复触发请求。

分步解决方案

1. 修正数据获取逻辑

请求成功后提取response.data作为API返回的真实数据,替换原错误的状态赋值:

const getWeatherData = async () => {
  try {
    // 替换{APIKEY}为你的OpenWeatherMap密钥
    const response = await axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${search}&appid={APIKEY}`);
    // 仅存储API返回的实际数据
    setWeatherData(response.data);
  } catch (err) {
    console.error(err);
  }
}

2. 调整状态与渲染逻辑

因为返回的是单个对象,初始状态设为null,渲染时先判断数据是否存在,再直接读取属性(注意国家信息在sys.country字段):

// 初始状态设为null,而非数组
const [weatherData, setWeatherData] = useState(null);

// 替换原map渲染逻辑
{weatherData && (
  <div>
    <h1>{weatherData.name}, {weatherData.sys.country}</h1>
  </div>
)}

3. 修复useEffect触发问题

用useCallback包裹getWeatherData避免重复创建函数,同时添加搜索按钮,防止输入时频繁请求API:

import { useEffect, useState, useCallback } from 'react'

// 用useCallback包裹,依赖search变量
const getWeatherData = useCallback(async () => {
  try {
    const response = await axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${search}&appid={APIKEY}`);
    setWeatherData(response.data);
  } catch (err) {
    console.error(err);
  }
}, [search])

// useEffect仅在getWeatherData变化时触发
useEffect(() => {
  getWeatherData()
}, [getWeatherData])

// 添加搜索按钮触发请求
const handleSearch = () => {
  getWeatherData()
}

// 输入框绑定value,避免状态不一致
<div className='inputContainer'>
  <input className='searchInput' type="text" onChange={handleChange} value={search} />
  <button onClick={handleSearch}>搜索天气</button>
</div>

修改后的完整代码

import axios from 'axios'
import { useEffect, useState, useCallback } from 'react'
import './App.css'

function App() {
  const [search, setSearch] = useState("london")
  const [weatherData, setWeatherData] = useState(null)

  const getWeatherData = useCallback(async () => {
    try {
      // 替换{APIKEY}为你的真实密钥
      const response = await axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${search}&appid={APIKEY}`);
      setWeatherData(response.data);
    } catch (err) {
      console.error(err);
    }
  }, [search])

  useEffect(() => {
    getWeatherData()
  }, [getWeatherData])

  const handleChange = (e) => {
    setSearch(e.target.value)
  }

  const handleSearch = () => {
    getWeatherData()
  }

  return (
    <div className="App">
      <div className='inputContainer'>
        <input className='searchInput' type="text" onChange={handleChange} value={search} />
        <button onClick={handleSearch}>搜索天气</button>
      </div>
      {weatherData && (
        <div>
          <h1>{weatherData.name}, {weatherData.sys.country}</h1>
          <p>当前温度:{(weatherData.main.temp - 273.15).toFixed(1)}°C</p>
        </div>
      )}
    </div>
  )
}

export default App

内容的提问来源于stack exchange,提问作者mohdh34m

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 05:06:28