React中使用对象getter属性,能否将this指向copyObj?
React中对象getter属性的this指向问题
问题原因
- 扩展运算符
{...obj}复制对象时,会调用getter获取当前值,将其作为静态属性复制到新对象,而非保留getter本身。所以你的copyObj里的values只是旧的数组,后续修改a/b不会触发重新计算。 - React状态更新是异步的,调用
setObj后立即访问obj拿到的还是旧状态,需要等组件重新渲染后才能获取最新值。
解决方案
方案1:每次更新时重新创建含getter的完整对象
直接构造包含最新属性和getter的新对象,getter的this自然指向新创建的对象:
const [obj, setObj] = useState(() => ({ a: valueA, b: valueB, get values() { if (!this.a || !this.b) { return []; } return [this.a, this.b]; } })); useEffect(() => { // 每次更新都重新创建带getter的对象 setObj({ a: valueA, b: valueB, get values() { if (!this.a || !this.b) { return []; } return [this.a, this.b]; } }); }, [valueA, valueB]); // 查看最新值需在组件重新渲染后 useEffect(() => { console.log(obj.values); // 这里会输出最新的values }, [obj]);
方案2:用Object.defineProperty保留getter
如果需要基于旧对象复制,可通过Object.defineProperty手动为新对象添加getter,确保this指向copyObj:
useEffect(() => { const copyObj = { a: valueA, b: valueB }; // 为新对象定义getter Object.defineProperty(copyObj, 'values', { get() { if (!this.a || !this.b) { return []; } return [this.a, this.b]; }, enumerable: true // 保证属性可被枚举(可选,按需添加) }); setObj(copyObj); }, [valueA, valueB]);
方案3:抽离getter逻辑避免重复代码
把getter的逻辑抽成独立函数,复用代码同时保证this指向正确:
// 抽离getter逻辑 const getValues = function() { if (!this.a || !this.b) { return []; } return [this.a, this.b]; }; const [obj, setObj] = useState(() => ({ a: valueA, b: valueB, get values() { return getValues.call(this); } })); useEffect(() => { setObj({ a: valueA, b: valueB, get values() { return getValues.call(this); } }); }, [valueA, valueB]);
关键说明
- 不要用扩展运算符直接复制带getter的对象,这会丢失getter特性,变成静态值。
- React状态更新异步,不要在
setObj后立即访问obj,需通过useEffect监听obj变化来获取最新状态。
内容的提问来源于stack exchange,提问作者Juhee Hong
相关产品推荐
相关产品推荐

