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,请求成功。
解决方案
可以通过以下两种方式避免无效请求:
- 添加参数有效性判断:在
WeatherContextProvider的useEffect中,先检查lat和lon是否为有效值,再发起请求:
useEffect(() => { const fetchAPI = async () => { if (lat && lon) { // 确保经纬度存在 setWeather(await getWeather(lat,lon)); } } fetchAPI(); }, [lat, lon])
- 设置初始状态默认值:给
LocationContextProvider的location初始状态设置lat和lon的默认值,比如null,后续判断时更清晰:
const [location, setLocation] = useState({ lat: null, lon: null })
内容的提问来源于stack exchange,提问作者Milad.eb96
相关产品推荐
相关产品推荐

