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

在React的useEffect中使用多个axios GET请求出现值未定义问题

解决OpenWeatherMap API串联请求的问题

你遇到的问题核心有两个:

  1. React的setState是异步操作,调用setCoordinates后立刻读取coordinate状态,此时状态还没更新,自然拿不到lat和lon
  2. OpenWeatherMap地理编码API返回的是数组(即使设置了limit=1),你把coordinate初始化为数组,但直接用coordinate['lat']是错误的,得先取数组里的第一个元素

直接给你修正后的代码,用async/await写法更直观,也避免异步状态的问题:

const Content = ({result}) => {
  const languages = [result['languages']]
  const [weather, setWeather] = useState(null) // 天气数据不是数组,初始化为null更合适
  const [coordinate, setCoordinates] = useState(null)
  const api_key = process.env.REACT_APP_API_KEY

  useEffect(() => {
    const fetchWeatherData = async () => {
      try {
        // 第一步:获取地理编码数据
        const geoResponse = await axios.get(
          `http://api.openweathermap.org/geo/1.0/direct?q=${result['capital']},${result['cca2']}&limit=1&appid=${api_key}`
        );
        // 因为返回的是数组,取第一个元素
        const geoData = geoResponse.data[0];
        if (!geoData) {
          console.error('未找到对应地理坐标');
          return;
        }
        setCoordinates(geoData);
        
        // 第二步:用拿到的经纬度请求天气数据
        const weatherResponse = await axios.get(
          `https://api.openweathermap.org/data/3.0/onecall?lat=${geoData.lat}&lon=${geoData.lon}&exclude=minutely,hourly,daily,alerts&appid=${api_key}`
        );
        setWeather(weatherResponse.data);
      } catch (error) {
        console.error('请求出错:', error);
      }
    };

    fetchWeatherData();
    // 注意:这里要把result和api_key加入依赖数组,避免闭包问题
  }, [result, api_key]);

  // 后续渲染逻辑...
};

如果坚持用链式then写法,也可以直接在第一个then里使用返回的数据,不用依赖状态:

useEffect(() => {
  axios
    .get(`http://api.openweathermap.org/geo/1.0/direct?q=${result['capital']},${result['cca2']}&limit=1&appid=${api_key}`)
    .then(geoResponse => {
      const geoData = geoResponse.data[0];
      if (!geoData) throw new Error('未找到地理坐标');
      setCoordinates(geoData);
      return geoData; // 把地理数据传递给下一个then
    })
    .then(geoData => {
      return axios.get(
        `https://api.openweathermap.org/data/3.0/onecall?lat=${geoData.lat}&lon=${geoData.lon}&exclude=minutely,hourly,daily,alerts&appid=${api_key}`
      );
    })
    .then(weatherResponse => {
      setWeather(weatherResponse.data);
    })
    .catch(error => {
      console.error('请求失败:', error);
    });
}, [result, api_key]);

另外提醒几点:

  • 天气API的exclude参数值不对,你写的exclude=1会报错,换成实际要排除的参数(比如minutely,hourly)或者删掉这个参数
  • 把result和api_key加入useEffect的依赖数组,去掉eslint-disable-next-line注释,避免闭包导致的旧值问题
  • 初始状态不要用空数组,天气和坐标都是对象,初始化为null更合理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 04:15:40