useReducer函数
对于拥有许多状态更新逻辑的组件来说,过于分散的事件处理程序可能会令人不知所措。对于这种情况,你可以将组件的所有状态更新逻辑整合到一个外部函数中,这个函数叫作Reducer。Reducer是处理状态的另一种方式。
1. 使用useReducer
jsx
import { useReducer } from 'react'
//由reducer函数完成外部逻辑的统一处理
function listReducer(state, action) {
// 其中action就是传值
switch (action.type) {
case 'add':
return [...state, {id:5, name:'baden'}]
case 'remove':
return state.filter(item => item.id !== action.id)
case 'edit':
return state.map(item => {
if(item.id === action.id) {
return {...item, name: "new"+item.name}
}else{
return item
}
})
}
}
function App() {
const [dataList, listDispatch] = useReducer(listReducer, [
{ id: 1, name: 'John' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Mark' },
{ id: 4, name: 'Trump' }
])
return (
<div>
<button onClick={()=>listDispatch({type: 'add'})}>添加</button>
<ul>
{
dataList.map(item => {
return (
<li key={item.id}>
{item.name}
<button onClick={()=>listDispatch({type:'edit', id: item.id})}>修改</button>
<button onClick={()=>listDispatch({type:'remove', id: item.id})}>删除</button>
</li>
)
})
}
</ul>
</div>
)
}
export default App
运行结果:
2. immer组件配合Reducer
在前面listReducer函数中state为状态值,不能直接修改导致处理数据比较繁琐,immer第三方库提供useImmerReducer方便我们进行处理:
jsx
import { useImmerReducer } from 'use-immer'
function listReducer(draft, action) {
// 其中action就是传值
switch (action.type) {
case 'add':
return draft.push({id:5, name:'baden'})
case 'remove':
const data = draft.find(item => item.id === action.id)
draft.splice(data, 1)
case 'edit':
const data = draft.find(item => item.id === action.id)
data.name = 'new'+data.name
}
}
function App() {
const [dataList, listDispatch] = useImmerReducer(listReducer, [
{ id: 1, name: 'John' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Mark' },
{ id: 4, name: 'Trump' }
])
return (
<div>
<button onClick={()=>listDispatch({type: 'add'})}>添加</button>
<ul>
{
dataList.map(item => {
return (
<li key={item.id}>
{item.name}
<button onClick={()=>listDispatch({type:'edit', id: item.id})}>修改</button>
<button onClick={()=>listDispatch({type:'remove', id: item.id})}>删除</button>
</li>
)
})
}
</ul>
</div>
)
}
export default App