Angular 学习笔记 immer 使用

更新 : 2021-01-29

immuta 字的由来

https://www.merriam-webster.com/dictionary/immutable

 

https://github.com/immerjs/immer#supported-object-types

 

immer 是用来做 immutable 的. 

angular 的 change detech 机制, 有时候为了要性能好一些,我们需要用 onPush 然后得配合 immutable 来让 input 触发. 

但是呢, immuable.js 写起来很丑, 原生 es6 得写法也不好看. 于是就有了 immer.

早前 immer 完全不支持 class 所以我就没有用,最近看了一下发现部分支持了. 所以开始用了.

import { produce, immerable } from "immer";

class Product {
    constructor(data?: Partial<Product>) {
        Object.assign(this, data);
    }
    [immerable] = true;
    date: Date;
    colors: Color[];
    private _price : number;
    public get price() : number {
        return this._price;
    }
    public set price(v : number) {
        this._price = v;
    }
}

class Color {
    constructor(data? : Partial<Color>) {
        Object.assign(this, data);
    }
    
    [immerable] = true;
    text: string
}

const product = new Product({ date: new Date(), price: 50, colors : [new Color({ text : 'dada' })]  });
const newProduct = produce(product, next => {
    next.price = 10;
});
console.log('instanceof Product', newProduct instanceof Product);
console.log('is new', newProduct !== product);
console.log('new value', newProduct.price === 10);

用法很简单. 调用, produce, 然后把对象传进去, next 是一个 proxy 对象, 我们像一般得操作方式就可以了, 最后会返回新得对象. 

它并不是 clone 整个子孙对象哦,而是你有修改才会 clone. 

如果是 class 要加上一个 symbol [immerable] = true

 

不支持的地方很多要特别注意哦 :

1. 如果要修改 Date 的, 必须自己 clone 一个新的. 

2. array 只可以修改 length 不可以自己添加额外的属性. 

3. prototype 是不会 clone 的, 保留原本指针

4. Built-in classes like Map and Set 不支持 (官网给了 workaround, 我也没用, 所以暂时不管)

5. 不支持 computed property (如果是一般写 getter setter 是可以的, 因为 getter setter 其实是 define 到了 prototype 上而不是对象上面, 如果你要 define 到对象上, 那 immer 就支持不到了)

 

posted @ 2019-05-18 11:38  兴杰  阅读(596)  评论(0编辑  收藏  举报