reacthooks确实好用,而且代码比class组件简单,但是有时候更新useState的数据不方便,比如声明数组的时候或者对象,设置的时候要传回一个函数,使用扩展操作符合并对象setValue((oldValue)=>({...oldValue,...newValue,}));在组件中这样看起来不是很美观,而且如果组件代码多一点,更新数据需要三行,尤其是用在if/for或者callback中的时候,就更难受了,所以我决定对useState做一个简单的封装,让它在组件中更新数据的时候更加优雅。先写几个工具函数isArray,isObject,isNotObjectfunctionisArray(value){returnvalueinstanceofArray;}functionisObject(value){returnvalueinstanceofObject&&!(valueinstanceofArray);}functionisNotObject(value){returntypeofvalue!=="object";}然后在我们自定义的钩子函数useSetState中,使用原来的useState来声明变量,变量可以直接返回,只需对_setValue做一些操作,返回一个新的setValue。在setValue中,如果initValue是数组,newsetValue传入单个值时会push,传入数组时会合并;如果initValue是对象,传入的对象会被合并,传入其他类型会报错。import{useState}from"react";导出默认函数useSetState(initValue){const[_value,_setValue]=useState(initValue);functionsetValue(newValue){//初始数据是一个数组if(isArray(initValue)){if(isArray(newValue)){_setValue((oldValue)=>[...oldValue,...newValue]);}else{_setValue((oldValue)=>[...oldValue,newValue]);}}//初始数据为对象elseif(isObject(initValue)){if(isObject(newValue)){_setValue((oldValue)=>({...oldValue,...newValue,}));}else{thrownewError(`${JSON.stringify(newValue)}不匹配初始数据类型!`);}}elseif(isNotObject(initValue)){_setValue(newValue);}}return[_value,setValue];}实际使用效果const[obj,setObj]=useSetState({a:1,b:2,});const[arr,setArr]=useSetState([{id:1},{id:2}]);setObj({c:3});//{a:1,b:2,c:3}setArr({id:3});//[{id:1},{id:2},{id:3}]
