首页 > 解决方案 > CSS 样式在 React 生命周期中应用在哪一点?

问题描述

我试图了解哪个生命周期点 CSS 样式开始应用于 DOM 元素。

遇到一个问题,我需要clientWidth在应用所有样式后获取元素。我的测试表明我不能依赖useEffect钩子,因为我得到的结果不一致。

我用一个简单的<did/>元素对其进行测试,该元素应该采用完整的父宽度(网格容器)。

const divRef = useRef()

useEffect(() => {
    console.log(divRef.current.clientWidth)    
})

<div class="parent">
    <div ref={divRef} class="child" />
</div>

我希望宽度 === 280 像素,但大多数时候(比如说)980 像素。如果我把console.log一切timeout都开始按预期工作。useEffect在应用样式之前明确运行。

有人可以为我澄清如何获得可靠的结果吗?

标签: javascriptcssreactjs

解决方案


class与 DOM 属性的发射和style属性相比,React 并没有真正涉及到 CSS 。它从不“应用” CSS,实际上您可能的意思可能是 DOM 中可能发生的一堆事情的集合:

  • 从已加载的样式表中生效的新样式
  • 由于窗口调整大小而改变布局
  • 由于应用了字体而发生重排

请参阅什么强制布局/重排以了解此范围。

可悲的是,当元素的布局发生变化或发生重排时,HTML 没有 DOM 事件,因此如果您需要获取元素尺寸,则必须修改它。一种简单的技术是定期检查 DOM 元素尺寸的轮询循环。如果您不想连续轮询,您可以在一段时间后切断轮询器并添加一个窗口调整大小事件侦听器来调整尺寸

function YourComponent() {
  const [width, setWidth] = useState(0);
  const divRef = useRef(null);

  function checkWidth() {
    if (divRef.current && divRef.current.clientWidth !== width) {
      setWidth(divRef.current.clientWidth);
    }
  }

  useEffect(() => {
    const interval = setInterval(checkWidth, 1000);
    return () => clearInterval(interval);
  }, []);

  useEffect(() => {
    window.addEventListener('resize', checkWidth);
    return () => window.removeEventListener('resize', checkWidth);
  }, []);

  return (
    <div ref={divRef}>
      ...
    </div>
  );
}


推荐阅读