immutable在前端是一个很重要的概念,因为前端的对象有快对象和慢对象的分别,所以在更新状态时尽量用一个新对象去替换旧对象,immer就是为了帮助你生成immutable对象的库。但是在react框架里我们就需要使用useImmer hook更方便一点,下面就是useImmer的手写:
import { Draft, freeze, produce } from "immer";
import { useCallback, useState } from "react";
export type DraftFunction<S> = (draft: Draft<S>) => void;
export type ImmerHook<S> = [S, (updater: S | DraftFunction<S>) => void];
export function useImmer<S = unknown>(intialValue: S | (() => S)): ImmerHook<S>;
export function useImmer<T>(intialValue: T) {
const [val, updateValue] = useState(() =>
freeze(typeof intialValue === "function" ? intialValue() : intialValue)
);
return [
val,
useCallback((updater: T | DraftFunction<T>) => {
if (typeof updater === "function") {
updateValue(produce(updater as DraftFunction<T>));
} else {
updateValue(freeze(updater));
}
}, []),
];
}
大家可以想一个问题:produce API是要传两个参数,这里为什么只需要1个?答案我放在评论区