immer
可持久化数据结构库
背景
js中的对象是可变的,因为使用了引用赋值,新的对象简单的引用了原始对象,改变新的对象会影响到原始对象,所以如果想要脱离这种相互影响的矛盾关系,引用值的修改需要进行深复制,但是因为一个属性而进行全部二就是过多的深复制就会浪费内存,耗损性能。
关键
所以我们采用节点分支树的方法来管理一个数据结构就是最完美的方式
我知道你可能不知道什么叫节点分支树的概念,你可以想想项目管理工具git的分支运作原理
使用语法
import produce from 'immer';
const array = [{value: 0}, {value: 1}, {value: 2}];
const arr = produce(array, draft => {
draft[0].value = 10;
});
console.log(arr === array);
//false
currentState
被操作对象的最初状态
draftState
根据 currentState 生成的草稿状态,它是 currentState 的代理,对 draftState 所做的任何修改都将被记录并用于生成 nextState 。在此过程中,currentState 将不受影响
nextState
根据 draftState 生成的最终状态
produce 生产
用来生成 nextState 或 producer 的函数
producer 生产者
通过 produce 生成,用来生产 nextState ,每次执行相同的操作
recipe 生产机器
用来操作 draftState 的函数
在react中用于管理state
如果state变更,React 的做法非常简单粗暴,直接将 原 VDOM 树上该节点以及该节点下所有的后代节点 全部删除,然后替换为新 VDOM 树上同一位置的节点,当然这个节点的后代节点也全都跟着过来了。
使用use-immer来替代你的useState
import React from "react";
import { useImmer } from "use-immer";
export default function () {
const [person, setPerson] = useImmer({
name: "张大炮",
age: '23'
});
function setName(name) {
setPerson(draft => {
draft.name = name;
});
}
function brithday() {
setPerson(draft => {
draft.age += 1;
});
}
return (
<div className="App">
<h1>
{person.name} ({person.age})
</h1>
<input
onChange={e => {
setName(e.target.value);
}}
value={person.name}
/>
<br />
<button onClick={brithday}>过生日</button>
</div>
);
}