使用沉浸器的JavaScript中的DeepCopy对象

时间:2019-03-05 09:08:09

标签: javascript reactjs redux immer.js

我正在使用immer转换react / redux状态。我还可以使用沉浸法仅复制对象而不进行转换吗?

__times

这是来自官方沉浸式自述文件。这是否意味着将空函数传递给import produce, {nothing} from "immer" const state = { hello: "world" } produce(state, draft => {}) produce(state, draft => undefined) // Both return the original state: { hello: "world"} 会返回原始状态或实际原始状态的深层副本?

非常感谢您的帮助:)!

2 个答案:

答案 0 :(得分:3)

这很容易用

进行测试
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是不可变的,您将无法对其进行更改。

我发现的另一件相当有趣的事情是,使用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 }

因此,回到最初的问题,是否可以通过不更改草稿中的任何内容来获得初始Object的深层副本。不,您不能,即使这样做(通过更改仅为愚弄而创建的属性),生成的克隆对象也将是不可变的,并没有真正的帮助。

答案 1 :(得分:0)

解决方案: Immer 的产品仅在更新时提供一个新的深度克隆对象。 您可以创建自己的生产函数,其行为与 immer 的生产函数类似,但每次使用 loadash 都会提供一个克隆对象

import _ fom 'lodash';
export default function produceClone(object, modifyfunction) {
    let objectClone = _.cloneDeep(object);
    if (!modifyfunction) return objectClone;
    modifyfunction(objectClone);
    return objectClone;
    }

无论您是否修改对象,这每次都会为您提供一个 deepCloned(或深度复制)对象。