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

探究reacthooks的本质——useCallback源码分析

时间:2023-03-27 01:19:04 JavaScript

这次我们来看useCallback。useCallback在所有原生使用中都是一个相对简单的函数。其实整体上和useRef/useState类似。我们直接看源码。初始化时主要执行以下代码:functionmountCallback(callback,deps){//获取当前钩子,即链表指针varhook=mountWorkInProgressHook();//deps是useCallback的第二个参数,即什么情况下需要更新回调varnextDeps=deps===undefined?空:部门;//hook.memoizedState中存储了两个值,这也是hooks代码的常用方法hook.memoizedState=[callback,nextDeps];//返回回调。就是传入什么,返回什么。returncallback;}关键是函数组件第二次渲染时要做什么:functionupdateCallback(callback,deps){//一般做法。varhook=updateWorkInProgressHook();//获取当前依赖值,它是一个数组varnextDeps=deps===undefined?空:部门;//获取之前的依赖值,用于比较。同样是一个数组,这个数组中[1]的值就是依赖值varprevState=hook.memoizedState;//检查以确保prevState存在。什么情况不存在?暂时不知道if(prevState!==null){//检测nextDeps的存在。这一行和上一行的判断可以结合起来。if(nextDeps!==null){//前面说了prevState上[1]的值就是之前的依赖值。varprevDeps=prevState[1];//判断当前依赖值是否等于上一个依赖值if(areHookInputsEqual(nextDeps,prevDeps)){//prevState[0]为上一个回调,说明函数没有变化,仍然是returnprevState[0];}}}//这里prevState不存在,或者nextDeps(当前值)和prevDeps(前一个值)不同//或者nextDeps不存在(等于改变,即如果第一个参数传入null,每次都会重新定义函数)hook.memoizedState=[callback,nextDeps];//返回一个新的函数returncallback;}附上areHookInputsEqual的源代码:functionareHookInputsEqual(nextDeps,prevDeps){{if(ignorePreviousDependencies){//仅当此组件正在热重载时为真。返回假;}}if(prevDeps===null){{error('%s在这次渲染中收到了一个最终参数,但在'+'之前的渲染中没有。即使最后一个参数是可选的,'+'它的类型不能改变在渲染之间。',currentHookNameInDev);}返回假;}{//不要在prod中比较长度,因为这些数组应该被传递//inline.if(nextDeps.length!==prevDeps.length){error('传递给%s的最后一个参数在渲染之间改变了大小。'+'这个数组的顺序和大小必须保持不变。\n\n'+'上一个:%s\n'+'传入:%s',currentHookNameInDev,"["+prevDeps.join(',')+"]","["+nextDeps.join(',')+"]");}}//只有这部分很重要,这里是浅比较for(vari=0;i