使用 produce
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
egghead.io lesson 3: Simplifying deep updates with _produce_
Immer 包导出了一个完成所有工作的 produce 函数。
produce(baseState, recipe: (draftState) => void): nextState
produce 接收一个基础状态(base state)和一个配方(recipe),该配方可用于对传入的 draft 执行所有期望的变更。Immer 的精妙之处在于 baseState 将保持不变,而 nextState 会反映对 draftState 所做的所有修改。
在配方内部,可以在 draft 对象上使用所有标准 JavaScript API,包括字段赋值、delete 操作,以及对数组、Map 和 Set 的变更操作(如 push、pop、splice、set、sort、remove 等)。
这些变更不必发生在根层级,而是允许在草稿(draft)内部的任意深度修改:draft.todos[0].tags["urgent"].author.age = 56
注意,配方函数本身通常不返回任何值。但若希望完全替换 draft 对象,可以返回一个新对象,详见返回新数据。
示例
import {produce} from "immer"
const baseState = [
{
title: "Learn TypeScript",
done: true
},
{
title: "Try Immer",
done: false
}
]
const nextState = produce(baseState, draftState => {
draftState.push({title: "Tweet about it"})
draftState[1].done = true
})
// the new item is only added to the next state,
// base state is unmodified
expect(baseState.length).toBe(2)
expect(nextState.length).toBe(3)
// same for the changed 'done' prop
expect(baseState[1].done).toBe(false)
expect(nextState[1].done).toBe(true)
// unchanged data is structurally shared
expect(nextState[0]).toBe(baseState[0])
// ...but changed data isn't.
expect(nextState[1]).not.toBe(baseState[1])
术语
(base)state:传递给produce的不可变状态recipe:produce的第二个参数,定义基础状态应如何"变更"draft:所有recipe的首个参数,作为原始基础状态的可安全变更代理(proxy)producer:使用produce的函数,通常形式为(baseState, ...arguments) => resultState
注意,配方函数的首个参数不必严格命名为 draft,可任意命名(如 users)。使用 draft 仅是约定俗成,暗示"此处允许变更"。