React钩子函数Reducer钩子函数超详解(2025版)

117 阅读2分钟

Reducer用途

Reducer统一的状态管理集合

  1. 对于拥有许多状态更新逻辑的组件来说,过于分散的事件处理程序可能会令人不知所措。对于这种情况,你可以将组件的所有状态更新逻辑整合到一个外部函数中,这个函数叫作 reducer。
  2. Reducer是处理状态的另一种方式

useReducer钩子

想要在一个函数组件中添加删除,添加,修改对数组管理操作的点击事件,可将这三种放在一个函数中统一管理。

function App() {
  const [list, disPatch] = useReducer(disList, [
    { id: 1, text: 'aaa' },
    { id: 2, text: 'bbb' },
    { id: 3, text: 'ccc' }
  ])
  return (
    <div>
      <button onClick={() => disPatch({type:'add'})}> 添加</button>
      {list.map((item) => {
        return (
          <li key={item.id}>
            {item.text}
            <button onClick={() => disPatch({type:'delet',id:item.id})}>删除</button>
            <button onClick={() => disPatch({type:'edit',id:item.id})}>修改</button>
          </li>
        )
      })}
    </div>
  )
}
export default App

在下面语法中const [list, disPatch] = useReducer(disList, [ { id: 1, text: 'aaa' }, { id: 2, text: 'bbb' }, { id: 3, text: 'ccc' } ])list是useReducer第二个参数也就是初始值,diaPatch是useReducer第一个参数disList也就是对list修改的方法。 onClick={() => disPatch({type:'edit',id:item.id}用箭头函数闭包来传递一个动态的 id 值。diaPatch()内用对象解构action的方式传递type值和当前作用的id。 下main是分立出的事件管理组件disList

function disList(state,action){
  switch(action.type)
{
  case'add':
  return [...state,{id:4,text:'ooo'}]
  case'delet':
  return (
    state.filter((item)=>{
        if(item.id===action.id)
          return false
        else
        return true
    }),
  )
  case'edit':
 return state.map((item)=>{
      if(item.id===action.id)
        return  {...item,text:'new'+item.text}
      else 
      return item
  })
}  
}

disList第一个参数state代表传递的变量状态,开始为list的初始值。第二个参数中action代表传递的事件类型,和当前操控item的id。用switch case语句,列举不同事件类型。

useImmerReduce钩子

用useImmerReduce改进只能用遍历操作对象的创建副本的方法。 直接调用包后,App主组件内代码不变。disList组件中改用draft。

import { useImmerReducer } from 'use-immer'
function disList(draft, action) {
  switch (action.type) {
    case 'add':
      draft.push({ id: 4, text: 'ooo' })
      break
    case 'delet':
      const index = draft.findIndex((item) => item.id === action.id)
      draft.splice(index, 1)
      break
    case 'edit':
      const value = draft.find((item) => item.id === action.id)
      value.text = 'new' + value.text
      break
  }
}