语法
2024年03月11日
一、useImmer
- App.ts
- useImmer.ts
import { useImmer } from "./hooks/useImmer";
function App() {
const [form, setForm] = useImmer({
a: "",
b: {
c: {
d: "",
},
},
});
const handleInputChange = (e: any) => {
const { value } = e.target;
setForm((draft)=>{
draft.b.c.d = value;
});
};
return (
<div>
<input value={form.b.c.d} onChange={handleInputChange}></input>
</div>
);
}
export default App;
import { produce,Draft, freeze } from "immer";
import { useCallback, useState } 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 UseImmer = <S = any>(initialValue: S | (() => S)) => ImmerHook<S>;
export const useImmer:UseImmer = (baseState: any) =>{
const [value, updateValue] = useState(() =>
freeze(typeof baseState === "function" ? baseState() : baseState, true)
);
return [
value,
useCallback((updater: any) => {
if (typeof updater === "function") updateValue(produce(updater));
else updateValue(freeze(updater));
}, []),
];
}
二、useState + immer
import { useState } from 'react';
import { produce } from "immer";
function App() {
const [form,setForm] = useState({
a: "",
b: {
c: {
d: ""
}
}
})
const handleInputChange = (e: any)=>{
const { value } = e.target;
const formNew = produce(form,(draft)=>{
draft.b.c.d = value;
});
setForm(formNew);
}
return (
<div>
<input value={form.b.c.d} onChange={handleInputChange}></input>
</div>
)
}
export default App
三、userImmerReducer
- App.ts
- userImmerReducer.ts
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;
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);
}
四、useReducer + immer
import { produce } from "immer";
import { useReducer } from "react";
const initialState = {
a: "",
b: {
c: {
d: ""
}
}
}
const reducer = produce((draft,action)=>{
switch(action.type){
case "change":
draft.b.c.d = action.value;
break;
default:
break;
}
})
function App() {
const [ form,dispatch ] = useReducer(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;