简体   繁体   English

CSS styles 应用于 React 生命周期的哪一点?

[英]On which point are CSS styles applied in the React lifecycle?

I'm trying to understand which lifecycle point CSS styles are starting to apply to DOM element(s).我试图了解哪个生命周期点 CSS styles 开始适用于 DOM 元素。

Run onto a problem where I need to get the element's clientWidth after all styles are applied.遇到一个问题,我需要在应用所有 styles 后获取元素的clientWidth My tests shows that I can not rely on useEffect hook, because I get inconsistent result.我的测试表明我不能依赖useEffect钩子,因为我得到的结果不一致。

I test it with a simple <did/> element, which is should take full parent width (grid container).我使用一个简单的<did/>元素对其进行测试,该元素应该采用完整的父宽度(网格容器)。

const divRef = useRef()

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

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

I expect the width === 280px, but get (lets say) 980px most of the time.我希望宽度 === 280 像素,但大多数时候(比如说)980 像素。 If I put console.log inside a timeout everything starts to work as expected.如果我将console.log放入timeout中,一切都会按预期开始工作。 Clearly useEffect runs before styles are applied.显然useEffect在应用 styles 之前运行。

Can someone clarify for me how I can get reliable result?有人可以为我澄清如何获得可靠的结果吗?

You can use the second argument of useEffect to keep track of the value of a variable.您可以使用 useEffect 的第二个参数来跟踪变量的值。

const divRef = useRef()
const [divWidth, setDivWidth] = React.useState('');

useEffect(() => {
    setDivWidth(divRef.current.clientWidth)    
}, [divWidth]) // Only re-run the effect if divWidth changes

I've also found another StackOverflow question that might help you:我还发现了另一个可能对您有所帮助的 StackOverflow 问题:

How to get the width of a react element 如何获取反应元素的宽度

React doesn't really get any more involved with CSS than emitting class and style attributes to DOM attributes. React 并没有真正参与到 CSS 中,而不是向 DOM 属性发出classstyle属性。 It never "applies" CSS, and really what you probably mean could be a conglomeration of a bunch of things that could be happening in the DOM:它永远不会“应用” CSS,实际上您可能的意思可能是 DOM 中可能发生的一堆事情的集合:

  • New styles taking effect from a stylesheet having loaded新的 styles 从加载的样式表生效
  • Layout changing due to window resizing由于 window 调整大小,布局发生变化
  • Reflow happens due to fonts being applied由于应用了 fonts 而发生回流

See What forces layout/reflow to get an idea of the scope of this.请参阅什么强制布局/回流来了解 scope。

Sadly, HTML doesn't have a DOM event for when an element's layout changes or when reflows occur, so if you need to get element dimensions, you have to hack it.遗憾的是,HTML 没有针对元素布局更改或回流发生时的 DOM 事件,因此如果您需要获取元素尺寸,则必须对其进行修改。 One unsophisticated technique is a polling loop that periodically checks the dimensions of the DOM element.一种简单的技术是定期检查 DOM 元素尺寸的轮询循环。 If you don't want to continuously poll, you could maybe cut off the poller after some time and add a window resize event listener to adjust the dimensions如果您不想连续轮询,您可以在一段时间后切断轮询器并添加 window resize 事件侦听器来调整尺寸

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>
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM