useReducer的简洁写法

580 阅读2分钟

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()