React通用钩子函数系列——useReducer()
来源于官方的解释:
对于拥有许多状态更新逻辑的组件来说,过于分散的事件处理程序可能会令人不知所措。对于这种情况,你可以将组件的所有状态更新逻辑整合到一个外部函数中,这个函数叫作 reducer
为什么要使用它
个人理解,reducer的出现是为了解决state不集中和降低数据更新逻辑复杂度的问题
比如这样:
<InputCustom
onChangeCallback: (value: any) => {
setStreamConfig({
...streamConfig,
ndi_hx: {
...streamConfig.ndi_hx,
multicast: {
...streamConfig.ndi_hx.multicast,
enable: value,
},
},
});
},
/>
使用state修改一个对象的属性值时,往往需要进行复杂的解构赋值和多层级操作,要知道这只是一个自定义输入组件,而在一个项目中,这样的组件将数不胜数,那么代码解构将变的十分臃肿,同一个state,更新的逻辑将分散在各个地方,并且其中可复用的逻辑也没有得到整理
如何使用
1.从比较中认识Reducer
在使用useState()的模式处理状态的情况中,一般包含以下步骤:
创建状态和状态设置的变量
const [state,setState] = useState(initData);
使用state表示状态
<div> {state} </div>
使用setState修改状态
const upData = () => {
setState(newData);
}
以useState()模式为基准,比较useReducer()模式处理状态的情况:
设置状态和状态调度的变量
const [state,stateDispatch] = useReducer(Reducer,initData);
这一步的差别在于,不再需要状态设置,而是将状态设置抽象为更高级别的状态调度,这更像一种专注单一状态修改,到集中调度多个状态修改的变更
其次,既然设置变更为调度,那么调度就需要有调度容器,这其中的Reducer就是调度容器
构建调度容器以及action
const stateReducer = (originalData,action) =>{
switch(action.type){
case 'type1':
// 修改逻辑
return newData;
case 'type2':
// 修改逻辑
return newData;
}
}
stateReducer调度容器函数有两个参数originalData和action,originalData即为原数据,action是一个自定义的对象,可以存储任何数据,同时它也是外部状态变更调度方法stateDispatch和调度容器的桥梁,通过设置type等相似的属性,可以让外部的调度程序使用相同的type来获取修改state的行为。对于自定义对象的其他属性,可以视为一组传入调度容器内部的自定义数据
使用state表示状态
<div> {state} </div>
这一步并没有什么变化,同第一步设置state一样,在Reducer中可以看出,状态还是状态,只是更新状态的方式有所不同
使用stateDispatch调度状态修改
const upData = () => {
stateDispatch(
// "action" 对象:
{
type: 'type1',
id: taskId,
}
);
}
这里的"action" 对象也就是传入第二步的action参数,通过这个action对象,可以告知Reducer容器,需要调度的行为。
总结
通过比较发现,useState()和useReducer()处理状态时,对状态的变化不会有太大差别,真正带来变化的,是设置和调度这两个思想变更,因此在使用useReducer()应该考虑应用于复杂的逻辑变更和高冗余的代码,而对于useState(),涉及到简单变量的变化用起来反而比useReducer()更简单。
评论区