核心函数

在Immer中,用于对数据进行的操作都是通过一个函数来进行的:produce。这个函数也是Immer包的默认导出,所以可以在使用的时候直接采用默认导入即可。

produce函数的签名也十分的简单,如以下所示。

produce<T>(currentState: T, recipe: (draftState: Draft<T>) => void): T

在这个函数签名中可以看出,其实如果要进行数据的修改,其实只需要两个元素:数据的原始状态和要进行的修改操作。所以produce函数可以接受的两个参数的功能是这样的。

  • currentState,这是所需要执行数据变化的基础数据状态,这个状态在操作中和操作结束后不会发生任何改变。
  • recipe,这是一个用于定义数据变化如何发生的函数,它需要接受一个参数,代表不可变对象的代理,其内容是不可变对象的原始状态,对不可变对象的代理构建的变化,将在最终被整合进新的不可变对象中。

以下是一个核心函数的应用示例。

import produce from 'immer';

const baseState = [
  { title: 'Star War', watches: 5 },
  { title: 'Star Trek', watches: 4 }
];

const newState = produce(baseState, draftState => {
  draftState[1].watches += 1;
});

在这个示例中,任何对draftState作出的修改,最终都将被应用到新的状态对象中。所以在recipe函数中,直接对其接受到的Draft<T>类型的参数进行所需要的修改即可。

在Immer库中,对这种调用produce函数建立新对象状态的函数有一个专用的名称:producer,其形式通常为(baseState, ...arguments) => resultState

传入produce函数中的recipe函数可以是异步的,如果在produce中使用异步的recipe,那么新对象将在返回的Promise被解析之后才会生成。