当前位置: 首页 > Web前端 > HTML

【ahooks源码系列解读】Dev篇——useTrackedEffect和useWhyDidYouUpdate

时间:2023-03-28 02:08:29 HTML

鍓嶈█鏈枃鏄痑hooks婧愮爜锛坴3.7.4锛夌郴鍒椻€斺€擠ev绡囩殑绗叚绡囥€備笂涓€绡囷細銆恆hooks婧愮爜绯诲垪瑙h銆戯紙涓婄瘒锛夊浣曡幏鍙栧拰鐩戝惉DOM鍏冪礌锛歶seEffectWithTarget銆恆hooks婧愮爜绯诲垪瑙h銆慏OM绡囷紙涓€锛夛細useEventListener銆乽seClickAway銆乽seDocumentVisibility銆乽seDrop銆乽seDrag銆恆hooks瑙h婧愮爜绯诲垪銆慏OM绡囷紙浜岋級锛歶seEventTarget銆乽seExternal銆乽seTitle銆乽seFavicon銆乽seFullscreen銆乽seHover銆恆hooks婧愮爜绯诲垪瑙h銆慏OM绡囷紙涓夛級锛歶seMutationObserver銆乽seInViewport銆乽seKeyPress銆乽seLongPress銆恆hooks婧愮爜绯诲垪瑙h銆慏OM绡囷紙鍥涳級锛歶seMouse,useResponsive,useScroll,useSize,useFocusWithin鏈枃涓昏瑙huseTrackedEffect鍜寀seWhyDidYouUpdate鐨勬簮鐮佸疄鐜帮紝璺熻釜鏄摢涓緷璧栧彉鍖栬Е鍙戜簡useEffect鐨勬墽琛屻€傚畼鏂规枃妗e熀鏈敤娉曟煡鐪嬫瘡娆℃墽琛屼竴涓猠ffect鏃跺彉鍖栫殑渚濊禆鍏崇郴瀹樻柟鍦ㄧ嚎DemoimportReact,{useState}from'react';import{useTrackedEffect}from'ahooks';exportdefault()=>{const[count,setCount]=浣跨敤鐘舵€侊紙0锛夛紱const[count2,setCount2]=useState(0);useTrackedEffect((changes)=>{console.log('鏇存敼渚濊禆椤圭殑绱㈠紩锛?,changes);},[count,count2],);return(

璇锋墦寮€娴忚鍣ㄦ帶鍒跺彴鏌ョ湅杈撳嚭锛?/p>

Count:{count}

setCount((c)=>c+1)}>count+1

Count2:{count2}

setCount2((c)=>c+1)}>count+1
);};鏍稿績瀹炵幇瀹炵幇鍘熺悊锛氶€氳繃uesRef璁板綍涓婁竴娆′緷璧栧€硷紝鍦ㄦ湰娆℃墽琛岃繃绋嬩腑锛屽垽鏂綋鍓嶄緷璧栧€间笌涓婃渚濊禆鍊兼槸鍚﹀彂鐢熷彉鍖朿hange:changeddependencyindexarraypreviousDeps:previousdependencycurrentDeps:currentdependencyuseTrackedEffect(effect:(changes:[],previousDeps:[],currentDeps:[])=>(void|(()=>void|undefined)),deps?:deps,)婧愮爜瀹炵幇constuseTrackedEffect=(effect:褰卞搷锛屼緷璧栵紵:DependencyList)=>{constpreviousDepsRef=useRef();//璁板綍鏈€鍚庝竴涓緷璧杣seEffect(()=>{//鍒ゆ柇渚濊禆鍓嶅悗鐨勫彉鍖朿onstchanges=diffTwoDeps(previousDepsRef.current,deps);constpreviousDeps=previousDepsRef.current;//璧嬪€兼渶鍚庝竴涓緷璧杙reviousDepsRef.current=deps;returneffect(changes,previousDeps,deps);},deps);};diffTwoDeps鏂规硶瀹炵幇锛氬墠鍚庝袱涓猟eps鐨勪緷璧栧叧绯诲垪琛ㄤ娇鐢∣bject.is涓ユ牸鐩哥瓑妫€鏌ュ鏋滃畾涔変簡deps1锛屽垯閬嶅巻deps1骞跺皢姣忎釜鍏冪礌涓巇eps2涓浉搴旂殑绱㈠紩鍏冪礌杩涜姣旇緝锛堢敱浜庢鍑芥暟浠呭湪璇ook涓娇鐢紝鍥犳鍋囧畾涓や釜deps鍒楄〃鐨勯暱搴﹀缁堢浉鍚岋級绛変簬杩斿洖-1涓嶇瓑浜庤繑鍥炵储寮曞€艰繃婊ゅ皬浜?鐨勫€硷紙鍗抽獙璇佺粨鏋滅浉绛夛級銆俧ilter((ele)=>ele>=0),鏈€鍚庡彧杩斿洖鏀瑰彉鍚庣殑鏁扮粍绱㈠紩鍊糲onstdiffTwoDeps=(deps1?:Deps2?:DependencyList)=>{//浣跨敤Object.is杩涜涓ユ牸鐨勭浉绛夋€ф鏌ュ湪returndeps1涔嬪墠鍜屼箣鍚庣殑涓や釜deps渚濊禆鍒楄〃涓婏紵deps1.map((_ele,idx)=>(!Object.is(deps1[idx],deps2?.[idx])锛焛dx:-1)).filter((ele)=>ele>=0)//杩囨护鐩哥瓑鐨勫€硷細deps2?deps2.map((_ele,idx)=>idx):[];};瀹屾暣婧愮爜useWhyDidYouUpdate甯姪寮€鍙戣€呮帓鏌ュ摢浜涘睘鎬у彉鍖栧鑷寸粍浠堕噸鏂版覆鏌撳畼鏂规枃妗e熀鏈敤娉曞畼鏂瑰湪绾緿emo鎵撳紑鎺у埗鍙帮紝鍙互鐪嬪埌鍙樺寲浜嗗睘鎬с€俰mport{useWhyDidYouUpdate}from'ahooks';importReact,{useState}from'react';constDemo:React.FC<{count:number}>=(props)=>{const[randomNum,setRandomNum]=useState(Math銆傞殢鏈虹殑锛堬級锛?useWhyDidYouUpdate('useWhyDidYouUpdateComponent',{...props,randomNum});杩斿洖(
number:{props.count}
randomNum:{randomNum}setRandomNum(Math.random)}style={{marginLeft:8}}>馃幉
);};exportdefault()=>{const[count,setCount]=useState(0);return(
setCount((prevCount)=>prevCount-1)}>count-setCount((prevCount)=>prevCount+1)}style={{marginLeft:8}}>count+
璇锋墦寮€娴忚鍣ㄦ帶鍒跺彴鏌ョ湅杈撳嚭锛?/p>
);};浣跨敤鍦烘櫙妫€鏌ュ摢浜涢亾鍏峰彂鐢熶簡鍙樺寲锛屽府鍔╁彂鐜版棤鏁堟覆鏌擄細useWhyDidYouUpdate浼氬憡璇夋垜浠洃鎺ф暟鎹腑鎵€鏈夊彂鐢熷彉鍖栫殑鏁版嵁锛屼笉绠℃槸鍚︽槸鏃犳晥鏇存柊锛屼絾鎴戜滑浠嶇劧闇€瑕佸尯鍒嗚瘑鍒摢浜涘睘鎬ф槸鏃犳晥鏇存柊锛屼粠鑰屼紭鍖栧疄鐜版€濊矾浣跨敤useRef澹版槑prevProps鍙橀噺锛堢‘淇濊幏鍙栨渶鏂扮殑鍊硷級鏉ヤ繚瀛樻渶鍚庣殑props銆倁seEffect姣忔鏇存柊鏃讹紝changedProps瀵硅薄閮戒細涓虹┖锛屾彁鍙栨柊鏃rops瀵硅薄鐨勫睘鎬э紝鐢熸垚灞炴€ф暟缁刟llKeys锛岄亶鍘哸llKeys鏁扮粍杩涜姣旇緝銆傛棫鐨勫拰鏂扮殑灞炴€у€笺€傚鏋滀笉鍚岋紝鍒欏皢鍏惰褰曞湪changedProps瀵硅薄涓€傚鏋渃hangedProps鏈夐暱搴︼紝鍒欒緭鍑烘敼鍙樼殑鍐呭骞舵洿鏂皃revProps鐨勬牳蹇冨疄鐜般€傚疄鐜板師鐞嗭細閫氳繃useEffect鑾峰彇涓婁竴涓猵rops鍊煎拰褰撳墠props鍊艰繘琛岄亶鍘嗘瘮杈冿紝濡傛灉鍊兼湁鍙樺寲鍒欒緭鍑?/componentName:瑙傚療缁勪欢鐨勫悕绉?/props:闇€瑕佽瀵熺殑鏁版嵁锛堝綋鍓嶇粍浠剁姸鎬佹垨浼犲叆鐨刾rops鍜屽叾浠栧彲鑳藉鑷撮噸鏂版覆鏌撶殑鏁版嵁锛夊鍑洪粯璁ゅ嚱鏁皍seWhyDidYouUpdate(componentName:string,props:IProps){constprevProps=useRef({});useEffect(()=>{if(prevProps.current){//鑾峰彇鎵€鏈夐渶瑕佽瀵熺殑鏁版嵁constallKeys=Object.keys({...prevProps.current,...props});constchangedProps:IProps={};//鏀瑰彉灞炴€у€糰llKeys.forEach((key)=>{//鍒ゆ柇鏄惁閫氳繃Object.is鏇存柊if(!Object.is(prevProps.current[key],props[key])){changedProps[key]={from:prevProps.current[key],to:props[key],};}});//閬嶅巻鍙樺寲鐨勫睘鎬э紝濡傛灉鏈夊€硷紝杈撳嚭鏃ュ織if(Object.keys(changedProps).length){console.log('[why-did-you-update]',componentName,changedProps);}}prevProps.c褰撳墠=閬撳叿锛泒);}瀹屾暣鐨勬簮浠g爜