React 相关面试题记录

198 阅读2分钟

面试题持续更新。。。

useLayoutEffect 和 useEffect 的区别

这两个hook都是react用于模拟生命周期和监听属性更新的hook。区别在于使用场景和执行时机。

hook使用场景执行时机
useLayoutEffect当需要使用Dom元素上的某些属性做操作时,可以使用useLayoutEffect,此时获取到的是dom生成后的dom属性dom生成之后,渲染更新之前
useEffect更新不依赖于dom元素状态,适合用于获取数据、绑定事件监听器等,不影响页面渲染页面渲染后,渲染线程空闲,准备下一次重绘前执行
哪个先执行?

useLayoutEffect 执行时机先于 useEffect

如果我给useEffect的函数设置async会报错吗?为什么?

会报错。因为如果给useEffectdispatch函数设置为async状态,函数返回的是一个Promise,不符合react源码的调度定义。在使用useEffect时,会初始化effect链,通过调用dispatch函数,返回destory函数,用于销毁时执行,如果用async,返回就是一个Promise了。

源码层面分析

源码中使用useEffectuseLayoutEffect会执行一个mouseEffect的函数,然后会调用pushEffect,具体的话可以看着这篇文章:React 源码的状态管理

// 表示一个调用层级,实际代码并非如此组织
commitLayoutMountEffects_complete() {
    commitLayoutEffectOnFiber() {
        ...
        commitHookEffectListMount(
            HookLayout | HookHasEffect,
            finishedWork,
        );
    }
}

commitHookEffectListMount(flags: HookFlags, finishedWork: Fiber) {
     // 当前effect对象的最后一个,react设置了成环
    const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
    if (lastEffect !== null) {
        const firstEffect = lastEffect.next;
        let effect = firstEffect;
        do {
             // Mount
            const create = effect.create;
            // 调用的create也就是effect hook的第一个参数:函数。这里也体现了上面说为啥不能用async
            effect.destroy = create();
        } while(effect !== firstEffect)
    }
}

工作中用到React版本是什么,你了解比较新的React版本的特性吗,比如React18