react - 05.useReducer

54 阅读2分钟

1.useReducer说明:

useReducer可以同时更新多个状态,当状态更新逻辑比较复杂的时候,就可以考虑使用useReducer了,相比useState,useReducer可以更好的描述如何更新状态

useReducer可以读取相关的状态,同时更新多个状态,useReducer负责更新状态的解耦模式,这样代码逻辑会更加清晰,代码行为更加易测,代码性能更高

2.useReducer语法说明:

const [state, dispatch] = useReducer(reducer, initState, initAction)

reducer:是一个回调函数,类似于(state, action) => newState,state是函数返回值,action是函数返回状态,state是状态值,dispatch是更新state的方法,也就是起到派发的作用,通过派发函数传参,去更新action的函数返回状态

3.useReducer使用注意事项:

useReducer和useState的作用类似,都用于声明和管理状态,在某些场景下,例如状态逻辑比较复杂并且包含多个子值,或者下一个状态依赖于之前的状态时,用useReducer,使用useReducer还能给那些会触发更新的组件做性能优化,因为可以向子组件传递dispatch,而不是回调函数

如果state的类型是一般数据类型,如Number,String,Boolean,建议使用useState,如果是引用数据类型,如Object,Array,建议使用useReducer

如果state关联变化,建议使用useReducer

如果业务逻辑很复杂,建议使用useReducer

如果state只想用在组件内部,建议使用useState,如果想维护全局state,建议使用useReducer

例子1 => 点击按钮修改状态:

import { useReducer } from 'react'
const App = () => {
  const [loading, dispatch] = useReducer((state: boolean, action: any) => {
    if (action.type == 'ok') {
      return !state
    }
    return state
  }, true)
  const handleChange = () => {
    dispatch({ type: 'ok' })
  }
  console.log(loading)
  return (
    <div>
      {loading}
      <button onClick={handleChange}>change</button>
      {
        loading ? <div></div> : <div></div>
      }
    </div>
  )
}
export default App

例子2 => 点击提交收集表单:

import { useReducer, useRef } from 'react'
const App = () => {
  const user = useRef<HTMLInputElement>(null)
  const pwd = useRef<HTMLInputElement>(null)
  const [formData, dispatch] = useReducer((state: object, action: any) => {
    return { ...state, ...action }
  }, {
    userName: "",
    passWord: ""
  })
  const [showState, showDispatch] = useReducer((state: boolean, action: any) => {
    if (action.type) {
      return !state
    }
    return state
  }, false)
  const handleLogin = () => {
    dispatch({
      type: 'login',
      data: {
        userName: user.current?.value,
        passWord: pwd.current?.value
      }
    })
  }
  const handleShow = () => {
    showDispatch({
      type: true
    })
  }
  if (formData.data) {
    console.log(formData.data)
  }
  return (
    <div>
      <h1>welcome</h1>
      userName: <input type="text" ref={user} /><br />
      passWord: <input type={showState ? 'text' : 'password'} ref={pwd} />
      <button onClick={handleShow}>{showState ? 'hide' : 'show'}</button><br />
      <button onClick={handleLogin}>login</button>
    </div>
  )
}
export default App

例子3 => 点击增减修改数量:

import { useReducer } from 'react'
const reducer = (state: number, action: any) => {
  console.log(state, action)
  switch (action.type) {
    case 'add':
      return state + 1
    case 'sub':
      return state - 1
    default:
      return state
  }
}
const App = () => {
  const [quantity, dispatch] = useReducer(reducer, 1)
  const handleSub = () => {
    dispatch({
      type: 'sub'
    })
  }
  const handleAdd = () => {
    dispatch({
      type: 'add'
    })
  }
  return (
    <div>
      <button onClick={handleSub} disabled={quantity <= 1 ? true : false}>-</button>
      <div>{quantity}</div>
      <button onClick={handleAdd} disabled={quantity >= 99 ? true : false}>+</button>
    </div>
  )
}
export default App