useEffect 第二个参数是否可以用表达式

1,625 阅读1分钟

判断第二个参数的源码

image.png

  • 其实就是遍历deps数组,对每一项执行Object.is()方法

useEffect 第二个参数是否可以使用 且与或

根据useEffect源码仿写useEffect

let memorizedState = [] // 寄存 hook
let index = 0 // hook 数组下标地位

const useEffect = (fn, dependencies) => {
  if(memorizedState[index]){
    // 不是第一次执行
    let lastDependencies = memorizedState[index] // 依赖项数组
    // 循环遍历依赖项是否与上次的值雷同
    let hasChanged = !areHookInputsEqual(dependencies, lastDependencies)
    
    if (hasChanged) {
      // 依赖项有扭转就执行 fn 函数
      index += 1
      memorizedState[index] = dependencies
      setTimeout(fn) // 设置宏工作,在组件render之后再执行
    } else {
      // 每个hook占据一个下标地位,避免程序错乱
      index += 1 
      memorizedState[index] = dependencies 
    }
  }else{
    // 第一次执行
    index += 1 
    memorizedState[index] = dependencies
    setTimeout(fn)
  }
}

const areHookInputsEqual = (nextDeps, prevDeps) => {
  if (prevDeps === null) {
    return false
  }
  if(prevDeps.length === 0) {
    return true
  }
  for (let i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
    if (Object.is(nextDeps[i], prevDeps[i])) {
      continue;
    }
    return false;
  }
  return true;
}

  • one =1 && two =1

    1. useEffect第二个接收的实际参数是 two
    2. 修改one值,参数接收1
    3. 修改two的值,会传入实际的值会触发回调
    4. && 在useEffect 第二个参数相当与 one ? Two : false
  • one = 1 || two =1

    1. useEffect第二个接收的参数值是 1
    2. one 修改会传入one的值
    3. 修改two值会传入two的值
    4. 原因: useEffect中hooks 记录的index 在one和two 修改值都会触发index 修改,这样对比的值相当与是上次one或者two修改的值对比传入的one或者two修改值,这样假如上次one修改值为3,这次tow修改值为3 对比则不会触发回调。