immer 如何处理带有映射和集合的对象键?
How does immer handle object keys with maps and sets?
immer docs 状态 "The keys of a map are never drafted! This is done to avoid confusing semantics and keep keys always referentially equal",但我很难理解这是什么意思。
我预计这意味着使用草稿对象作为草稿 Map
/Set
中的键会自动取消引用该键,就好像我调用了例如map.set(original(key) || key, value)
。然而,事实并非如此,我不明白那句话是什么意思。
这里有一些例子可以证明我的意思。我预计所有这些日志 true
。
const { enableMapSet, produce } = immer;
enableMapSet();
const collection = {
map: new Map(),
set: new Set(),
storedAsObject: {},
storedAsDraft: {},
};
collection.set.add(collection.storedAsObject);
collection.map.set(collection.storedAsObject, 'value');
const newCollection = produce(collection, (draft) => {
console.log(draft.set.has(draft.storedAsObject)); // false
console.log(draft.map.has(draft.storedAsObject)); // false
draft.set.add(draft.storedAsDraft);
draft.map.set(draft.storedAsDraft, 'value');
});
console.log(newCollection.set.has(newCollection.storedAsDraft)); // true
console.log(newCollection.map.has(newCollection.storedAsDraft)); // false
<script src="https://unpkg.com/immer@6.0.3/dist/immer.umd.production.min.js"></script>
特别是,最后两个的差异似乎是一个错误,但文档中谈论的特殊行为只调用地图,所以我不确定。
这意味着如果您获取 Map 的键,并且它们是对象,您将不会取回草稿(就像您获取值时那样),而是取回原始对象。
所以你不应该改变地图中使用的键。 (例如 Array.from(draftMap.keys())[0].counter++
之类的东西不会被 Immer 处理)
immer docs 状态 "The keys of a map are never drafted! This is done to avoid confusing semantics and keep keys always referentially equal",但我很难理解这是什么意思。
我预计这意味着使用草稿对象作为草稿 Map
/Set
中的键会自动取消引用该键,就好像我调用了例如map.set(original(key) || key, value)
。然而,事实并非如此,我不明白那句话是什么意思。
这里有一些例子可以证明我的意思。我预计所有这些日志 true
。
const { enableMapSet, produce } = immer;
enableMapSet();
const collection = {
map: new Map(),
set: new Set(),
storedAsObject: {},
storedAsDraft: {},
};
collection.set.add(collection.storedAsObject);
collection.map.set(collection.storedAsObject, 'value');
const newCollection = produce(collection, (draft) => {
console.log(draft.set.has(draft.storedAsObject)); // false
console.log(draft.map.has(draft.storedAsObject)); // false
draft.set.add(draft.storedAsDraft);
draft.map.set(draft.storedAsDraft, 'value');
});
console.log(newCollection.set.has(newCollection.storedAsDraft)); // true
console.log(newCollection.map.has(newCollection.storedAsDraft)); // false
<script src="https://unpkg.com/immer@6.0.3/dist/immer.umd.production.min.js"></script>
特别是,最后两个的差异似乎是一个错误,但文档中谈论的特殊行为只调用地图,所以我不确定。
这意味着如果您获取 Map 的键,并且它们是对象,您将不会取回草稿(就像您获取值时那样),而是取回原始对象。
所以你不应该改变地图中使用的键。 (例如 Array.from(draftMap.keys())[0].counter++
之类的东西不会被 Immer 处理)