useReducer简洁写法,用useState的时候老是有要手动合并的问题,一直在探索用useReducer来代替useState, 用来解决自动合并的问题,每次使用的时候就不用3个点了
const initial = { name: 'xj', age: 18 }
const [state, setState] = useReducer(
(prev: typeof initial, next: Partial<typeof initial>) =>
({ ...prev, ...next }),
initial
)
使用
setState({sex:'male'}) //的到的数据是自动合并后的数据{ name: 'xj', age: 18 ,sex: 'male'}
带回调函数的形式,用来解决重置数据的问题,也可以使用switch
const initial = { name: 'xj', age: 18 }
type Ts = Partial<typeof initial> & { [x: string]: any }
const [state, setState] = useReducer(
(prev: Ts, next: Ts | { (x?: Ts): Ts }) =>
typeof next === 'function' ? next(prev) : { ...prev, ...next },
initial
)
使用
setState(() => initial)//将数据重置
setState((prev) => ({...prev})) //伪代码,表示可以拿到上一个值,和useState的设置函数的回调函数形式一样
也可以这样,
enum Type {
reset,
set,
}
const initial = { name: "xj", age: 18 };
type Ts = Partial<typeof initial> & { [x: string]: any };
type Tn = Ts & { type?: number };
const [state, setState] = useReducer(
(prev: Ts, next: Tn | { (x?: Ts): Ts }) => {
if (typeof next === "function") return next(prev);
switch (next.type) {
case Type.reset:
return initial;
case Type.set: {
const { type, ...rest } = next;
return rest;
}
default:
return { ...prev, ...next };
}
},
initial
);
也可以不要提示,用any,看起来会更简洁,但是不推荐
const [state, setState] = useReducer(
(prev: any, next: any) => ({ ...prev, ...next }),
{ name: 'xj', age: 18 })
const [state, setState] = useReducer(
(prev: any, next: any) => (typeof next === 'function' ? next(prev) : { ...prev, ...next }),
{ name: 'xj', age: 18 })
如果用不上上一个state,可以去掉回调函数的参数
const [state, setState] = useReducer(
(prev: any, next: any) => (typeof next === 'function' ? next() : { ...prev, ...next }),
{ name: 'xj', age: 18 })
是不是简洁到爆,你是不是会爱上useReducer, 虽然useState是基础hook,useReducer是进阶hook,但是useState使用useReducer来实现的
小建议: useState,和useReducer使用的时候都不能直接修改state,这个state必须要拷贝一份,一般有多层级的时候可以用多个useState或useReducer将数据结构打平到顶层,如果数据有嵌套的引用类型,要修改依赖的时候要深拷贝一份再改,可以用JSON.stringify,JSON.parse或者用immutable.js的fromJS(state).toJS()