userImmerReducer
2023年05月28日
一、认识
二、定义
import { produce, Draft,nothing } from "immer"
import { useMemo, useReducer } from "react";
export type DraftFunction<S> = (draft: Draft<S>) => void;
export type Updater<S> = (arg: S | DraftFunction<S>) => void;
export type ImmerHook<S> = [S, Updater<S>];
export type ImmerReducer<S, A> = (
draftState: Draft<S>,
action: A
) => void | (S extends undefined ? typeof nothing : S);
export type Reducer<S = any, A = any> = ImmerReducer<S, A>;
export const useImmerReducer = <S,A,I>(reducer: ImmerReducer<S, A>,initializerArg:S & I ,initializer?: (arg: S & I) => S)=>{
const cachedReducer = useMemo(() => produce(reducer), [reducer]);
return useReducer(cachedReducer, initializerArg as any, initializer as any);
}
三、使用
import { useImmerReducer,ImmerReducer } from "./hooks/useImmerReducer";
const initialState = {
a: "",
b: {
c: {
d: "",
},
},
}
const reducer:ImmerReducer<any,any> = (draft, action) => {
switch (action.type) {
case "change":
draft.b.c.d = action.value;
break;
default:
break;
}
}
function App() {
const [form, dispatch] = useImmerReducer(reducer, initialState);
const handleInputChange = (e: any) => {
const { value } = e.target;
dispatch({
type: "change",
value,
});
};
return (
<div>
<input value={form.b.c.d} onChange={handleInputChange}></input>
</div>
);
}
export default App;