Reducer用途
Reducer统一的状态管理集合
- 对于拥有许多状态更新逻辑的组件来说,过于分散的事件处理程序可能会令人不知所措。对于这种情况,你可以将组件的所有状态更新逻辑整合到一个外部函数中,这个函数叫作 reducer。
- 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
}
}