> For the complete documentation index, see [llms.txt](https://linqiang-miao.gitbook.io/github/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://linqiang-miao.gitbook.io/github/immer.md).

# Immer

## 不可变\[可共享]数据结构

1. 对象，数组，map，set 等创建后，内部状态不可以修改的数据结构。
2. 可共享：新建一个数据结构，未修改部分共享旧的部分，修改部分采用新的。

## 不可变共享数据结构优点

> Immutable data structures allow for (efficient) change detection: if the reference to an object didn't change, the object itself did not change. In addition, it makes cloning relatively cheap: Unchanged parts of a data tree don't need to be copied and are shared in memory with older versions of the same state.

1. 便于判断对象是否改变，只需比较引用，无需深度比较
2. 克隆更方便，没变的部分保持旧的引用，节省内存空间

## immer 做了什么

1. 检测突变并抛出错误
2. 帮我们用普通的 js 操作，便可以实现不可变数据结构

## curried producers

```js
const curried = produce((draft, ...rest) => {})
const nextState = curried(state, ...rest)
```

## react & immer

1. useState + produce
2. useImmer
3. useReducer + produce
4. useImmerReducer
5. redux + immer

## api

1. produce 返回的值默认是 递归 freeze 的
2. current() original()

## patches 补丁

* applyPatches
* produceWithPatches
* todo： 多次 produce，如何快速还原？

## 性能优化

* 对大对象提前 shallow freeze

## producer 的返回值

1. 直接在 draft 上修改，无需 return
2. 不改动 draft 直接返回新数据， return newData
3. 返回 undefined， return nothing

## Use with Typescript

1. 多使用 readonly，借助 utility type Immutable

## Immer vs Immutable.js

1. immer 比较方便，直接使用原生语法即可，immutable 需要使用提供的 api
2. 性能方面：当数据不是超大时，都可胜任；数据超大时，immutable 的性能比较好；但是 immutable 的数据结构不是原生 js，需要转成原生 js 的话 比较耗费性能，比 immer 性能差
