文章在 github 开源, 欢迎 Fork 、Star !
前言
Immer 是 mobx 的作者写的一个 immutable 库,核心实现是利用 ES6 的 proxy,几乎以最小的成本实现了 js 的不可变数据结构,简单易用、体量小巧、设计巧妙,满足了我们对JS不可变数据结构的需求。
无奈网络上完善的文档实在太少,所以自己写了一份,本篇文章以贴近实战的思路和流程,对 Immer 进行了全面的讲解。
目录
数据处理存在的问题
先定义一个初始对象,供后面例子使用:
首先定义一个currentState
对象,后面的例子使用到变量currentState
时,如无特殊声明,都是指这个currentState
对象
let currentState = {
p: {
x: [2],
},
}
哪些情况会一不小心修改原始对象?
// Q1
let o1 = currentState;
o1.p = 1; // currentState 被修改了
o1.p.x = 1; // currentState 被修改了
// Q2
fn(currentState); // currentState 被修改了
function fn(o) {
o.p1 = 1;
return o;
};
// Q3
let o3 = {
...currentState
};
o3.p.x = 1; // currentState 被修改了
// Q4
let o4 = currentState;
o4.p.x.push(1); // currentState 被修改了
解决引用类型对象被修改的办法
- 深度拷贝,但是深拷贝的成本较高,会影响性能;
- ImmutableJS,非常棒的一个不可变数据结构的库,可以解决上面的问题,But,跟 Immer 比起来,ImmutableJS 有两个较大的不足:
- 需要使用者学习它的数据结构操作方式,没有 Immer 提供的使用原生对象的操作方式简单、易用;
- 它的操作结果需要通过
toJS
方法才能得到原生对象,这使得在操作一个对象的时候,时刻要注意操作的是原生对象还是 ImmutableJS 的返回结果,稍不注意,就会产生意想不到的 bug。
看来目前已知的解决方案,我们都不甚满意,那么 Immer 又有什么高明之处呢?
immer功能介绍
安装immer
欲善其事必先利其器,安装 Immer 是当前第一要务
npm i --save immer
immer如何fix掉那些不爽的问题
Fix Q1、Q3
import produce from 'immer';
let o1 = produce(currentState, draft => {
draft.p.x = 1;
})
Fix Q2
import produce from 'immer';
fn(currentState);
function fn(o) {
return produce(o, draft => {
draft.p1 = 1;
})
};
Fix Q4
import produce from