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

React Context中数据获取先报400错误后正常的原因咨询

页面刷新时先出现400错误后成功获取数据的原因分析

问题描述

刷新页面时,会先触发400错误,随后又能成功获取到天气数据,请问该问题的原因是什么?

相关代码

位置上下文(LocationContextProvider)代码

import React, {useState, useEffect, createContext} from 'react';

import { getLocation } from '../api';

export const LocationContext = createContext();

const LocatonContextProvider = (props) => {

const [location, setLocation] = useState({})

useEffect(() => {
    const fetchAPI = async () => {
        setLocation(await getLocation());
    }

    fetchAPI();
}, [])

return (
    <LocationContext.Provider value={location}>
        {props.children}
    </LocationContext.Provider>
);
};

export default LocatonContextProvider;

天气上下文(WeatherContextProvider)代码

import React, {useState, useEffect, createContext, useContext} from 'react';

 //api
 import { getWeather } from '../services/api';

//Context
import { LocationContext } from '../contexts/LocationContextProvider';

export const WeatherContext = createContext()

const WeatherContextProvider = ({children}) => {

const location = useContext(LocationContext);
const lat = location.lat;
const lon = location.lon;

const [weather, setWeather] = useState({});

useEffect(() => {
    const fetchAPI = async () => {
        setWeather(await getWeather(lat,lon));
    }
    fetchAPI();
}, [lat, lon])

return (
    <WeatherContext.Provider value={weather}>
        {children}
    </WeatherContext.Provider>
);
};

export default WeatherContextProvider;

Axios请求封装代码

import axios from "axios";

const getLocation = async () => {

const LOCATION_URL = 'http://ip-api.com/json/?fields=country,city,lat,lon,timezone';

const response = await axios.get(LOCATION_URL);
return response.data;
}

const getWeather = async (lat, lon) => {

const WEATHER_URL = `https://api.openweathermap.org/data/2.5/weather? lat=${lat}&lon=${lon}&appid=bac9f71264248603c36f011a991ec5f6`;

const response = await axios.get(WEATHER_URL)
return response.data;
}

export {getLocation, getWeather};

原因分析

  • 初始状态缺失导致无效请求:LocationContextProvider的初始location状态是空对象{},所以WeatherContextProvider初始化时,lat和lon的值为undefined。此时useEffect会立即执行,调用getWeather(undefined, undefined),生成的请求URL中lat和lon参数无效,触发OpenWeatherMap API的400错误(缺少必要的经纬度参数)。
  • 后续状态更新触发有效请求:当LocationContextProvider中的getLocation请求完成后,location状态被更新为包含有效lat和lon的对象。此时WeatherContextProvider中的lat和lon发生变化,useEffect再次触发,传入正确的经纬度调用getWeather,请求成功。

解决方案

可以通过以下两种方式避免无效请求:

  1. 添加参数有效性判断:在WeatherContextProvider的useEffect中,先检查lat和lon是否为有效值,再发起请求:
useEffect(() => {
    const fetchAPI = async () => {
        if (lat && lon) { // 确保经纬度存在
            setWeather(await getWeather(lat,lon));
        }
    }
    fetchAPI();
}, [lat, lon])
  1. 设置初始状态默认值:给LocationContextProvider的location初始状态设置lat和lon的默认值,比如null,后续判断时更清晰:
const [location, setLocation] = useState({ lat: null, lon: null })

内容的提问来源于stack exchange,提问作者Milad.eb96

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 15:36:20