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

React与JavaScript中如何存储JSON响应供其他函数使用

问题原因

fetchWeatherForecast是异步函数,直接调用不会立即返回接口响应的JSON对象,只会返回Promise实例。你把Promise直接传入数据解析函数,自然无法读取到weather、main这类实际响应才有的属性,最终拿不到正确结果。

正确实现方案

核心思路

用React内置的useState存储接口返回的JSON数据,在组件挂载、或者需要刷新数据的时机,通过useEffect触发接口请求,请求成功后把响应结果存入状态,所有业务函数统一从状态中读取数据做解析,同时做好加载、错误态的边界处理,避免渲染报错。


第一步:优化fetchData.js的容错逻辑

  • 修正原代码中内部变量和函数重名的问题
  • 接口请求失败时统一返回null,方便上层逻辑判断请求状态
  • 给所有数据解析函数加可选链和默认值,避免数据为空时访问属性抛出错误
import { weatherAPIConfig } from "../weatherAPIConfig"

export async function fetchWeatherForecast(cityName) {
    const URL = `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&units=metric&appid=${weatherAPIConfig.key}`
    try {
        const res = await fetch(URL)
        if (!res.ok) throw new Error("Request failed")
        return await res.json()
    } catch (error) {
        console.log("Could not find given city");
        return null
    }
}

export function getWeatherDescription(weatherForecastJSON) {
    return weatherForecastJSON?.weather?.[0]?.description ?? "暂无数据";
}

export function getWeatherTemperature(weatherForecastJSON) {
    return weatherForecastJSON?.main?.temp ?? "暂无数据"
}

export function getWeatherWindSpeed(weatherForecastJSON) {
    return weatherForecastJSON?.wind?.speed ?? "暂无数据";
}

export function getWeatherHumidity(weatherForecastJSON) {
    return weatherForecastJSON?.main?.humidity ?? "暂无数据"
}

第二步:改造Row组件,用状态存储响应数据

  • 新增三个状态:weatherData存接口返回的完整JSON、loading标记加载状态、error存储错误信息
  • 组件首次挂载时触发数据拉取,请求完成后把结果存入weatherData
  • 按加载中、加载失败、正常展示的顺序做条件渲染,数据正常时再调用解析函数从weatherData中取值渲染
import React, { useState, useEffect } from 'react'
import {getWeatherDescription, getWeatherHumidity, getWeatherTemperature, getWeatherWindSpeed, fetchWeatherForecast} from '../../functions/fetchData'
import { weatherAPIConfig } from '../../weatherAPIConfig';

function Row() {
    // 存储接口返回的完整JSON数据,初始值为null
    const [weatherData, setWeatherData] = useState(null)
    const [loading, setLoading] = useState(true)
    const [error, setError] = useState("")

    // 组件挂载时拉取数据
    useEffect(() => {
        const loadWeatherData = async () => {
            setLoading(true)
            setError("")
            const res = await fetchWeatherForecast("London")
            if (!res) {
                setError("无法获取对应城市天气数据")
            } else {
                setWeatherData(res)
            }
            setLoading(false)
        }
        loadWeatherData()
    }, [])

    if (loading) return <div>数据加载中...</div>
    if (error) return <div>{error}</div>

    return (
        <div>
            <div>API-key: {weatherAPIConfig.key}</div>
            <div>天气描述: {getWeatherDescription(weatherData)}</div>
            <div>温度: {getWeatherTemperature(weatherData)}℃</div>
            <div>风速: {getWeatherWindSpeed(weatherData)}m/s</div>
            <div>湿度: {getWeatherHumidity(weatherData)}%</div>
        </div>
    )
}

export default Row;

后续如果要在其他业务函数里使用这份天气数据,直接读取weatherData状态传入对应解析函数即可,不需要重复发起接口请求。如果需要切换查询城市,只需要重新调用fetchWeatherForecast传入新城市名,拿到结果后调用setWeatherData更新状态,所有引用该状态的视图都会自动同步更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 07:51:24