1. //因为useEffect可以被调用多次,所以使用数组 prevDepsAry = [[name], [count]]
    2. let prevDepsAry = [];
    3. // 每次组件重新渲染effectIndex都会在render方法中置为0
    4. let effectIndex = 0
    5. function useEffect(callback, depsAry) {
    6. // 首先判断callback是不是函数
    7. if(Object.prototype.toString.call(callback) !== '[object Funtion]') throw new Error("useEffect的第一个参数必须为函数")
    8. // 判断 depsAry 有没有被传递,没有被传递的话每次都调用传入的函数
    9. if(typeof depsAry === 'undefined'){
    10. // 调用传入的函数
    11. callback()
    12. }else{
    13. // 判断depsAry是不是数组, 如果不是数组直接返回错误信息
    14. if(Object.prototype.toString.call(depsAry) !== '[object Array]') throw new Error('useEffect第二个参数应为数组')
    15. // 获取上一次的状态值
    16. let prevDeps = prevDepsAry[effectIndex]
    17. // 判断depsAry数组中传入的值是否有变化
    18. let hasChanged = depsAry.every((dep, index) => dep === prevDeps[index]) === false
    19. // 如果有变化,调用传过来的函数
    20. if(hasChanged){
    21. callback()
    22. }
    23. //同步依赖值
    24. prevDepsAry[effectIndex] = depsAry
    25. effectIndex++
    26. }
    27. }

    疑问:

    1. // 这段代码有什么作用
    2. prevDepsAry[effectIndex] = depsAry
    3. effectIndex++

    正如useState调用多次一样,useEffect同一页面也可以调用多次,所以也需要index与prevDepsAry数组做存储。