对于拥有许多状态更新逻辑的组件来说,过于分散的事件处理程序可能会令人不知所措。对于这种情况,你可以将组件的所有状态更新逻辑整合到一个外部函数中,这个函数叫做 reducer
Reducer 是处理状态的另一种方式
使用 useReduer
import { useReducer } from "react"
// 由着reducer函数完成外部逻辑的统一处理
function listReducer(state,action) {
switch (action.type) {
case 'add':
return [...state,{id:4,text:'ddd'}]
case 'edit':
return state.map((item) => {
if (item.id===action.id) {
return {...item,text:'new'+item.text}
}
else {
return item
}
})
case 'remove':
return state.filter((item) => {
if (item.id===action.id) {
return false
}
else {
return true
}
})
}
}
export default function App() {
const [list, listDispatch] = useReducer(listReducer, [
{id:1,text:'aaa'},
{id:2,text:'bbb'},
{id:3,text:'ccc'},
])
return (
<div>
hello App
<input type="text" /><button onClick={()=>listDispatch({type:'add'})}>添加</button>
<ul>
{list.map((item) => {
return (
<li key={item.id}>
{item.text}
<button onClick={() => listDispatch({type:'edit',id:item.id})}>编辑</button>
<button onClick={() => listDispatch({type:'remove',id:item.id})}>删除</button>
</li>
)
})}
</ul>
</div>
)
}
使用 useImmerReducer
import { useImmerReducer } from 'use-immer'
// 由着reducer函数完成外部逻辑的统一处理
function listReducer(draft, action) {
let value = draft.find((item) => item.id === action.id)
let index = draft.findIndex((item) => item.id === action.id)
switch (action.type) {
case 'add':
draft.push({ id: 4, text: 'ddd' })
break
case 'edit':
value.text = 'new' + value.text
break
case 'remove':
draft.splice(index,1)
break
}
}
export default function App() {
const [list, listDispatch] = useImmerReducer(listReducer, [
{id:1,text:'aaa'},
{id:2,text:'bbb'},
{id:3,text:'ccc'},
])
return (
<div>
hello App
<input type="text" /><button onClick={()=>listDispatch({type:'add'})}>添加</button>
<ul>
{list.map((item) => {
return (
<li key={item.id}>
{item.text}
<button onClick={() => listDispatch({type:'edit',id:item.id})}>编辑</button>
<button onClick={() => listDispatch({type:'remove',id:item.id})}>删除</button>
</li>
)
})}
</ul>
</div>
)
}