这很容易测试
import { produce } from 'immer'
const state = {
hello: 'world',
}
const nextState = produce(state, draft => {})
nextState.hello = 'new world'
console.log(state, nextState)
哪个输出
Object { hello: "new world" }
Object { hello: "new world" }
这意味着它不会创建对象的深层副本。
更新:
所以我很感兴趣并测试了这个库,这是我的发现。
我上面写的代码片段只是库中的一个优化,如果没有进行任何更改,它会返回旧状态。但是,如果您进行一些更改,则库将开始按预期运行,并且以后无法进行突变。那是,
const state = {
hello: 'world',
}
const nextState = produce(state, draft => {
draft.hello = 'new world';
})
nextState.hello = 'newer world';
console.log(state, nextState)
会导致错误: TypeError: "world" is read-only
这意味着您的 newState 是不可变的,您不能再对其执行更改。
我发现的另一个相当有趣的事情是 immer 在使用class
实例时失败。那是,
class Cls {
prop = 10;
}
const instance = new Cls();
const obj = {
r: instance,
};
const newObj = produce(obj, draft => {
draft.r.prop = 15;
});
console.log(obj, newObj);
结果是
r: Object { prop: 15 }
r: Object { prop: 15 }
所以回到最初的问题,你能否通过在草案中不做任何更改来获得初始对象的深层副本。不,您不能,即使您这样做了(通过更改创建的属性可能只是为了愚弄 immer),生成的克隆对象将是不可变的,并且没有真正的帮助。