前情概要
本文不打算过多讲述Immer原理,喜欢深究的小伙伴可以参考这篇文章 immer原理
举一个简单例子
const initialUser = {
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
};
function User() {
const [user, setUser] = useState(initialUser);
return (
<div>
<label>修改 user.address.geo.lat </label>
<input
value={user.address.geo.lat}
onChange={e => {
setUser({
...user,
address: {
...user.address,
geo: {
...user.address.geo,
lat: e.target.value
}
}
})
}}
/>
</div>
)
}
如果你的 state 嵌套很深,您可能需要考虑将其扁平化,但是如果你不想更改 state 的结构,更喜欢使用嵌套扩展的快捷方式。当你修改一个复杂结构对象的某一属性的状态时,需要重复使用三点运算扩展符把其他属性平铺,作为一个学过使用过vue的码农,这能忍???
import { useImmer } from 'use-immer';
const [data, setData] = useImmer({
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
});
//添加一项
setData(draft => {
draft.name = 'John';
});
//减少count
setData(draft => {
draft.company.name = 'Romaguera';
});
工作原理
简单来讲跟vue3的双向绑定底层原理一样,使用了Proxy API 代理了对象和数组,文笔太差描述不到位,喜欢深究的可借鉴 immer源码解读