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

ReactJS更新useState对象时丢失getter的问题及解决方法问询

问题根源

你用{...example}拷贝出来的是普通JavaScript对象,并非ExampleObject类的实例——类的getter/setter是定义在原型链上的,普通对象继承不到这些方法,所以更新后访问example.property2会找不到对应的getter,只能直接取私有属性_property2。

解决方案

要保留getter/setter,核心是确保更新后的状态依然是ExampleObject的实例,以下是几种可行方法:

方法1:给类添加克隆方法(推荐)

在ExampleObject中新增一个克隆实例的方法,直接基于当前实例创建新实例,天然保留所有原型方法:

export class ExampleObject {
    constructor(p1, p2) {
        this._property1 = p1;
        this._property2 = p2;
    }

    // 新增克隆方法
    clone() {
        return new ExampleObject(this._property1, this._property2);
    }

    // 原有的getter/setter不变
    get property1(){ return this._property1 }
    set property1(val){ this._property1 = val }
    get property2(){ return this._property2 }
    set property2(val){ this._property2 = val }
}

子组件中更新状态时,先克隆实例再修改:

const ChildComponent1 = ({example, setExample}) => {
    const handleTextContent = (event) => {
        const newExample = example.clone();
        newExample.property1 = event.target.value; // 用类的setter赋值
        setExample(newExample);
    }

    return(
         <textarea
              value={example.property1}
              onChange={handleTextContent}>
         </textarea>
    );
}

方法2:直接构造新实例

如果类的属性不多,也可以直接用当前实例的属性值构造新对象:

const ChildComponent1 = ({example, setExample}) => {
    const handleTextContent = (event) => {
        // 用当前实例的属性值创建新实例
        const newExample = new ExampleObject(event.target.value, example.property2);
        setExample(newExample);
    }

    return(
         <textarea
              value={example.property1}
              onChange={handleTextContent}>
         </textarea>
    );
}

方法3:用Object.create保留原型链

如果不想修改ExampleObject类,可以通过Object.create创建继承自类原型的新对象,再拷贝原有属性:

const ChildComponent1 = ({example, setExample}) => {
    const handleTextContent = (event) => {
        // 创建继承自ExampleObject原型的新对象
        const newExample = Object.create(ExampleObject.prototype);
        // 拷贝原实例的私有属性
        Object.assign(newExample, example);
        // 用setter更新属性
        newExample.property1 = event.target.value;
        setExample(newExample);
    }

    return(
         <textarea
              value={example.property1}
              onChange={handleTextContent}>
         </textarea>
    );
}
额外优化:去掉冗余state

你原本在子组件中维护了textContent这个额外state,其实可以直接绑定example.property1到textarea, onChange时直接更新状态,避免多层同步的问题,代码更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:41:08