javascript - React 组件生命周期:render 和 return 有什么区别,return 之后会发生什么?
问题描述
这是一个关于 React 组件生命周期中概念的广义问题。下面是一些示例代码。请把代码当作一个模糊的参考。
const Modal = ({
className,
variant,
width,
withCloseIcon,
isOpen: propsIsOpen,
onClose: tellParentToClose,
renderLink,
renderContent,
}) => {
const [stateIsOpen, setStateOpen] = useState(false);
const isControlled = typeof propsIsOpen === 'boolean';
const isOpen = isControlled ? propsIsOpen : stateIsOpen;
const $modalRef = useRef();
const $clickableOverlayRef = useRef();
const closeModal = useCallback(() => {
if (!isControlled) {
setStateOpen(false);
} else {
tellParentToClose();
}
}, [isControlled, tellParentToClose]);
useEffect(() => {
console.log('check useEffect')
document.body.style.overflow = 'hidden'; // why bother? since always return "visible"
return () => {
document.body.style.overflow = 'visible';
};
}, [isOpen]);
return (
<Fragment>
{isOpen &&
ReactDOM.createPortal(
<ScrollOverlay>
<ClickableOverlay variant={variant} ref={$clickableOverlayRef}>
<StyledModal
className={className}
ref={$modalRef}
>
{withCloseIcon && <CloseIcon type="close" variant={variant} onClick={closeModal} />}
{renderContent({ close: closeModal })}
</StyledModal>
</ClickableOverlay>
</ScrollOverlay>,
$root,
)}
</Fragment>
);
};
我注意到在功能组件中,我传递给钩子 useEffect() 的函数是在 return() 执行后执行的。(在 useEffect() 中定义的仅在其他控制台日志在内部的方法中console.log('check useEffect')
执行后才执行)。renderContent
return()
我知道根据定义,
useEffect()
在组件完成渲染后调用。那么完成是什么意思render
呢?组件“渲染”和组件“返回”之间的关系是什么(React 功能组件)
在里面
useEffect()
,我们总是在返回document.body.style.overflow = 'visible';
,所以为什么还要document.body.style.overflow = 'hidden';
在返回之前跑呢?
解决方案
首先,让我们定义一些关键字。
什么是油漆?
绘制:当用户代理将渲染树转换为屏幕上的像素时,它执行了一次“绘制”(或“渲染”)。形式上,我们认为用户代理在执行更新事件循环的渲染步骤时已经“渲染”了一个文档。
它是什么render
以及它是如何工作的?
基本上,渲染过程是浏览器绘制,只需要更多步骤。React 需要定义(重新)渲染什么和不渲染什么。此过程也称为和解。
问题 1
useEffect
等待浏览器完成绘制,以便您的渲染过程不会被您的useEffect
执行阻塞。如果您不想等待油漆完成,您可以使用useEffectLayout
问题2
查看 Dan Abramov(React 的核心成员之一)的这篇精彩文章
问题 3 和 Q1 的第一部分
我无法比这个人解释得更好。所以也检查一下这个。 https://stackoverflow.com/a/65225493/7942117
推荐阅读
- c++ - 循环永远不会开始
- mongodb - Mongo 函数创建集合
- scala - 如何从 Akka Event Stream 构建 Akka Streams Source?
- inno-setup - 如何在 Inno Setup 中检查一个字符串是否以另一个 (EndsWith) 结尾
- python - 如何让滚动窗口从熊猫的未来(后续)窗口中迭代?
- sql-update - 如果更新值不是 Null 或 Empty,如何使用触发器在物化视图表中设置父表更新值
- python - python - 如何将数据保存到python django中的数据库中,列表形式和列表是字典的集合?
- unity3d - unity3d 预制件问题预制件不会发生
- android - Flutter:使用 EventChannel 的 PlatformException
- python - SQLAlchemy 别名列“类型对象'MiscUnit'没有属性'codeLabel'”