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

React对象类型状态更新:三种方式的有效性与选型对比

React对象状态更新的三种写法:有效性与选择理由

一、三种写法的有效性

  • 第一种写法有效:

    setFormData(Object.assign({}, formData, {b: 22}));
    

    Object.assign会先创建空对象,把formData的所有属性拷贝过去,再覆盖b的值为22,最终返回全新对象,完全满足React状态更新必须传递新引用的要求。

  • 第二种写法有效:

    setFormData((prevData) => ({
        ...prevData,
        b: 22
    }));
    

    这是React推荐的函数式更新写法:React会自动把当前最新状态传给prevData参数,我们用ES6扩展运算符浅拷贝旧状态,再更新b属性并返回新对象。这种方式能确保拿到最新状态,避免闭包捕获旧值导致的错误。

  • 第三种写法无效:

    setFormData( { ...prevData, "b": 22 } )
    

    这里的prevData是未定义的变量,直接写会抛出ReferenceError。React不会自动把状态值注入到普通对象字面量中,必须通过函数式更新的回调参数才能获取prevData。

二、选择不同写法的理由

选Object.assign的情况

  • 需要兼容不支持ES6扩展运算符的老旧环境时,Object.assign作为ES5标准API,兼容性更好
  • 当需要合并多个源对象时,Object.assign可一次性传递多个参数(比如Object.assign({}, obj1, obj2, obj3)),写法比多次使用扩展运算符更简洁

选函数式更新(箭头函数+扩展运算符)的情况

  • 当状态更新依赖前一次状态时,必须用这种写法。比如连续点击按钮累加数值、在定时器/API回调里更新状态,函数式更新能保证每次拿到的都是最新状态,避免闭包导致的旧值问题
  • 日常开发中,扩展运算符的写法比Object.assign更直观、可读性更高,尤其是仅更新少数属性的场景

第三种写法为什么不能用

核心原因是prevData未定义,React不会自动生成这个变量。如果想用扩展运算符更新状态,必须将其放入函数式更新的回调中,参考第二种写法的格式。


内容的提问来源于stack exchange,提问作者gene b.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 00:12:08