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

React中如何用useState向数组追加元素?状态更新问题求助

解决React useState数组追加元素被覆盖的问题

问题根源

你当前的写法有两个核心问题:

  1. 错误的数组更新逻辑:在setData里用[{...prev, ...newItem}]是把之前的数组prev当成对象展开,再和新对象合并,最后包裹成只有一个元素的新数组——这相当于每次都把数组替换成当前循环的单个元素,自然会覆盖之前的内容。
  2. 频繁触发状态更新:在forEach里循环调用setData,每次循环都会触发组件重渲染,既影响性能,也容易导致状态更新异常。

最优解决方案:一次性转换数据后更新

既然接口返回的是完整的国家数组,没必要逐个循环更新状态,直接把所有数据转换成你需要的格式,再一次性设置状态即可:

const LightMode = () => {
    const [data, setData] = useState([])

    useEffect(() =>{
        axios.get('https://restcountries.com/v3.1/all').then(res=>{
            // 用map一次性转换所有国家数据
            const formattedCountries = res.data.map(country => ({
                name: country.name.common,
                population: country.population,
                region: country.region,
                capital: country.capital,
                image: country.coatOfArms.png
            }));
            // 一次性设置状态
            setData(formattedCountries);
        })
    }, [])

    console.log(data)

    return(
        <div>
            <NavigationBar />
            <div className='temp'>
                {/* 修复可选链写法:data[0]?.image 而不是 data?[0].image */}
                <Card className='country-cards'>
                    <Card.Img variant='top' src={data[0]?.image || null}/>
                    <Card.Body>
                        <Card.Title>{data[0]?.name || ''}</Card.Title>
                    </Card.Body>
                </Card>
            </div>
        </div>
    )
}

export default LightMode;

如果确实需要逐个追加元素(不推荐)

如果业务场景必须逐个添加元素,要使用正确的数组展开语法:把之前的数组展开,再追加新元素,写法是[...prev, newItem],但注意不要在循环里频繁调用setData,避免不必要的重渲染:

// 仅作示例,不推荐在循环中频繁调用
setData(prev => [...prev, {
    name: country.name.common,
    population: country.population,
    region: country.region,
    capital: country.capital,
    image: country.coatOfArms.png
}])

额外修复点

你在JSX里的data?[0].image是错误的可选链写法,应该改成data[0]?.image,这样才能正确判断数组第一个元素是否存在,避免报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:45:57