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

React中useState处理对象数组时DOM不渲染数据的问题求助

React天气应用数据无法渲染问题修复

问题描述

开发React天气小应用时,通过latLongStore循环调用axios获取多城市天气数据,请求正常但weatherData数组内容无法在DOM中显示——数组长度正确但无内容渲染。

代码片段

...
const latLongStore = [
  { latitude: 23.8315, longitude: 91.2868, title: "Agartala", color: "#299617", code: 'VEAT' },
  { latitude: 23.0225, longitude: 72.5714, title: "Ahmedabad", color: "#299617", code: 'VCBI' },
...
]

const initialData = {
    city: '',
    latitude: 0,
    longitude: 0,
    max_temperature: 0,
    min_temperature: 0
}

function TableView(props) {
    const [weatherData, updateWeatherData] = useState([initialData]);

    useEffect(() => {
        
            latLongStore.forEach((latLong) => {
                axios.get(`api-url`).then((response) => {

                    const fetchedData = {
                        city: latLong.title,
                        latitude: response.data.latitude,
                        longitude: response.data.longitude,
                        max_temperature: response.data.daily.temperature_2m_max[0],
                        min_temperature: response.data.daily.temperature_2m_min[0]
                    }

                    console.log(fetchedData);

                    updateWeatherData(weatherData => [...weatherData, fetchedData]);
                })
            })
    }, []);

    switch (weatherData.length) {
        default:
            return (
                <div>
                    <br />
                    <br />
                    <br />
                    <br />

                    LOADING...
                    {weatherData.length}
                </div>
            )
        // weatherData contains 62 objects after fetch but no values show up in DOM
        case 62:
            return (
                <div>
                   <br />
                    <br />
                    <br />
                    <br />
                    { weatherData.forEach((data) => {
                        <div>
                            { data.city } : { data.latitude }, { data.longitude }
                        </div>
                    }) }
                </div>
            )
        // default:
        //     return (
        //         <div>
        //             <br />
        //             <br />
        //             <br />
        //             <br />
        //             LOADING...
        //         </div>
        //     )
    }

}

export default TableView;

输出现象

  • 加载过程中:显示LOADING...和数组长度递增
  • 数组长度达到62后:仅显示空白,无城市数据内容

修复方案

1. 替换forEach为map实现列表渲染

JSX中渲染列表必须使用map,因为forEach仅执行遍历操作无返回值,无法生成React可识别的元素数组。map会返回每个元素对应的JSX节点,同时要为列表元素添加唯一key属性(优先使用数据自身的唯一标识,比如城市code)。

修改case 62的渲染代码:

case 62:
    return (
        <div>
            <br />
            <br />
            <br />
            <br />
            { weatherData.map((data) => (
                <div key={data.code}>
                    { data.city } : { data.latitude }, { data.longitude }
                </div>
            )) }
        </div>
    )

2. 优化请求与状态更新逻辑

当前循环调用updateWeatherData会触发多次组件重渲染,且初始状态包含无效空数据,建议用Promise.all批量处理请求,一次性更新状态,提升性能:

useEffect(() => {
    // 批量生成所有请求的Promise
    const fetchTasks = latLongStore.map(latLong => 
        axios.get(`api-url`)
            .then(res => ({
                city: latLong.title,
                latitude: res.data.latitude,
                longitude: res.data.longitude,
                max_temperature: res.data.daily.temperature_2m_max[0],
                min_temperature: res.data.daily.temperature_2m_min[0]
            }))
    );

    // 等待所有请求完成后一次性更新状态
    Promise.all(fetchTasks)
        .then(allData => updateWeatherData(allData))
        .catch(err => console.error('天气数据请求失败:', err));
}, []);

同时将初始状态改为空数组,避免混入无效数据:

const [weatherData, updateWeatherData] = useState([]);

3. 简化加载判断逻辑

无需依赖固定长度62判断加载完成,直接根据数组是否为空判断,逻辑更健壮:

// 替换原switch逻辑
if (weatherData.length === 0) {
    return (
        <div>
            <br />
            <br />
            <br />
            <br />
            LOADING...
        </div>
    );
}

return (
    <div>
        <br />
        <br />
        <br />
        <br />
        { weatherData.map((data) => (
            <div key={data.code}>
                { data.city } : { data.latitude }, { data.longitude }
            </div>
        )) }
    </div>
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:20:43