React函数组件render与return区别及return后执行逻辑相关问题
问题1:useEffect()提到的“render完成”具体指什么?
这里的render完成不是指组件函数执行完return语句,而是指完整的渲染链路全部走完:
- React已经完成新旧虚拟DOM的diff计算
- 所有需要更新的真实DOM改动都已经提交到浏览器,完成挂载/更新
- 浏览器已经完成页面绘制,用户可以看到最新的渲染结果
这之后才会按顺序触发所有useEffect的回调函数。
问题2:React函数式组件中,“render(渲染)”和“returns(返回)”的关联是什么?
return只是渲染流程中的一个环节:
- 组件触发重渲染后,会先执行整个组件函数的同步代码,执行到return语句时会产出本次渲染对应的JSX结构,这一步只是完成了组件自身的逻辑计算,和真实DOM没有任何关系。
- 拿到return的JSX后,React才会继续走后续的diff、真实DOM更新、浏览器绘制流程,整个链路走完才算渲染完成。
你观察到的renderContent里的console.log早于useEffect里的打印,就是因为renderContent是组件函数执行阶段(return之前)同步调用的,而useEffect要等整个渲染流程全部结束才会触发。
问题3:为什么useEffect里要先执行document.body.style.overflow = 'hidden',清理函数再改回visible?
两者的执行时机完全不同,不会冲突,这是模态框的标准交互实现:
- 当
isOpen变为true,模态框渲染完成后,会触发useEffect的回调,把body的overflow设为hidden,目的是禁止用户滚动背景页面,避免模态框打开时背景还能上下滑动的问题。 - 清理函数并不会和当前effect回调同时执行,它只会在两种场景下触发:一是
isOpen发生变化(比如变为false关闭模态框),先执行上一次effect的清理函数;二是组件直接卸载。这时候把overflow改回visible,就是恢复页面的正常滚动能力。
补充:你贴的代码实际存在小问题,当isOpen为false时effect还是会把overflow设为hidden,不符合预期,正常实现需要加isOpen的判断,只有模态框打开时才设置禁止滚动。
内容的提问来源于stack exchange,提问作者Kid_Learning_C
相关产品推荐
相关产品推荐

