跳至正文
Wener Notes

immer

约 2 分钟阅读
  • 默认会 autofreeze - 损失一点性能,返回不可变对象
  • 大 list 可以先 freeze 在进行 produce
  • 不能有循环引用
TypeScript
import assert from 'node:assert/strict';
import test from 'node:test';
import { produce } from 'immer';
import { createStore } from 'zustand';
import { immer } from 'zustand/middleware/immer';

test('immer', () => {
  const o: Record<string, any> = {
    a: { v: 0 },
    b: { v: 0 },
    c: { v: 0 },
  };

  // by produce
  {
    const o2 = produce(o, (s) => {
      s.b.v = 1;
    });

    assert.equal(o2.b.v, 1);
    // 没变
    assert(o.a === o2.a);
    assert(o.b !== o2.b);
  }
  {
    const store = createStore(
      immer(() => {
        return o;
      }),
    );
    store.setState((s) => {
      s.a.v = 0;
      s.b.v = 1;
    });
    let next = store.getState();
    // same
    assert(o.a === next.a);
    assert(o.b !== next.b);
    assert(!Object.isFrozen(next)); // not frozen
    // all frozen
    assert(Object.isFrozen(next.a));
    assert(Object.isFrozen(next.b));
    assert(Object.isFrozen(next.c));

    // set by merge instead of produce
    store.setState({ b: o.b });
    next = store.getState();
    assert(o.b === next.b);

    assert(!Object.isFrozen(next)); // not frozen
    assert(Object.isFrozen(next.a)); // frozen
    assert(!Object.isFrozen(next.b)); // not frozen
  }

  {
    const state = {
      a: { v: 1 },
      b: { v: 1 },
      c: { v: 1 },
      d: { v: 1 },
    };
    const next = produce(state, (s) => {
      s.a.v++;
      s.b.v++;
      s.b.v--;
      s.c.v = 1;
    });

    assert(state !== next);
    assert(state.a !== next.a); // 变了
    assert(state.b !== next.b);
    assert.deepEqual(state.b, next.b); // 变了,但相同
    assert(state.c === next.c); // 没变
    assert(state.d === next.d); // 没变

    assert(Object.isFrozen(next));
    assert(Object.isFrozen(next.a));
    assert(Object.isFrozen(next.b));
    assert(Object.isFrozen(next.c)); // 没变 依然 frozen
    assert(Object.isFrozen(next.d)); // frozen
  }
});

关联信息

反向链接、本文链接的其他页面和外部资料。

反向链接

  • mutative
    笔记 · immer

    unadlib/mutative · MIT, TS · 类似于 immer · 默认不 freeze · 使用重放的机制 - 性能更好 · shallow copy · 暴露更多内部可配置功能 - 更高的定制化能力 · 没有全局配置 · 支持 async

参考资料

GitHub3 条
其他外链1 条
最近更新commit ef1d424编辑