跳至主内容区

Map 和 Set

[非官方测试版翻译]

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

⚠ 从第 6 版开始,必须显式启用对 MapSet 的支持。请在应用启动时调用一次 enableMapSet()

普通对象、数组、MapSet 始终会被 Immer 草稿化。以下是在 Immer 中使用 Map 的示例:

test("Producers can update Maps", () => {
const usersById_v1 = new Map()

const usersById_v2 = produce(usersById_v1, draft => {
// Modifying a map results in a new map
draft.set("michel", {name: "Michel Weststrate", country: "NL"})
})

const usersById_v3 = produce(usersById_v2, draft => {
// Making a change deep inside a map, results in a new map as well!
draft.get("michel").country = "UK"
})

// We got a new map each time!
expect(usersById_v2).not.toBe(usersById_v1)
expect(usersById_v3).not.toBe(usersById_v2)
// With different content obviously
expect(usersById_v1).toMatchInlineSnapshot(`Map {}`)
expect(usersById_v2).toMatchInlineSnapshot(`
Map {
"michel" => Object {
"country": "NL",
"name": "Michel Weststrate",
},
}
`)
expect(usersById_v3).toMatchInlineSnapshot(`
Map {
"michel" => Object {
"country": "UK",
"name": "Michel Weststrate",
},
}
`)
// The old one was never modified
expect(usersById_v1.size).toBe(0)
// And trying to change a Map outside a producers is going to: NO!
expect(() => usersById_v3.clear()).toThrowErrorMatchingInlineSnapshot(
`"This object has been frozen and should not be mutated"`
)
})

由 Immer 生成的 Map 和 Set 会被人工设置为不可变。这意味着如果在生产者(producer)外部尝试调用 setclear 等变更方法,它们将抛出异常。

注意:Map 的 键(keys) 永远不会被草稿化!这样做是为了避免语义混淆,并确保键始终保持引用相等