Reactjs 我希望这个useRef和useffect组合会失败……为什么它会成功呢?

Reactjs 我希望这个useRef和useffect组合会失败……为什么它会成功呢?,reactjs,react-hooks,Reactjs,React Hooks,我希望此useffect在第一次渲染时失败,因为我假设innerCarouseRef.current在第一次渲染时未定义,它调用getBoundingClientRect。它为什么工作/为什么在运行useffect时定义了innerCarouseRef.current import React from 'react'; import { debounce } from 'lodash'; export default function Carousel({ RenderComponen

我希望此
useffect
在第一次渲染时失败,因为我假设
innerCarouseRef.current
在第一次渲染时未定义,它调用
getBoundingClientRect
。它为什么工作/为什么在运行
useffect
时定义了
innerCarouseRef.current

 import React from 'react';
 import { debounce } from 'lodash';

 export default function Carousel({ RenderComponent }) {
  const [innerCarouselWidth, setInnerCarouselWidth] = React.useState(0);
  const [itemWidth, setItemWidth] = React.useState(0);
  const innerCarouselRef = useRef();
  const itemRef = useRef();
  const content = data.map((el, i) => {
    return (
      <div key={`item-${i}`} ref={i === 0 ? itemRef : undefined}>
        <RenderComponent {...el} />
      </div>
    );
  });
  useEffect(() => {
    const getElementWidths = () => {
      setInnerCarouselWidth(innerCarouselRef.current.getBoundingClientRect().width); // why doesn't this call to getBoundingClientRect() break?
      setItemWidth(itemRef.current.getBoundingClientRect().width);
    };
    getElementWidths();
    const debouncedListener = debounce(getElementWidths, 500);
    window.addEventListener('resize', debouncedListener);
    return () => window.removeEventListener('resize', debouncedListener);
  }, []);
 return (
    <div className="inner-carousel" ref={innerCarouselRef}>
      {content}
    </div>
  )
}
从“React”导入React;
从“lodash”导入{debounce};
导出默认函数旋转木马({RenderComponent}){
const[innerCarouselWidth,setInnerCarouselWidth]=React.useState(0);
const[itemWidth,setItemWidth]=React.useState(0);
const innerCarouselRef=useRef();
const itemRef=useRef();
const content=data.map((el,i)=>{
返回(
);
});
useffect(()=>{
常量getElementWidths=()=>{
setInnerCarouselWidth(innerCarouseRef.current.getBoundingClientRect().width);//为什么对getBoundingClientRect()的调用没有中断?
setItemWidth(itemRef.current.getBoundingClientRect().width);
};
getElementWidths();
const debouncedListener=debounce(getElementWidths,500);
window.addEventListener('resize',debouncedListener);
return()=>window.removeEventListener('resize',debouncedListener);
}, []);
返回(
{content}
)
}

React在更新DOM后运行效果(我们通常希望它以这种方式工作)。在您的情况下,该效果在安装组件后运行,因此设置了
innerCarouseRef.current


我建议您阅读这些文档以便更好地理解。

谢谢!我很熟悉useEffect文档……但我也想知道,既然我在这里进行DOM度量,为什么不需要使用
useLayoutEffect
?如果我可以使用
useffect
完美地测量DOM,为什么
useLayoutEffect
会存在呢?
useLayoutEffect
会在浏览器将DOM绘制到屏幕之前运行,
useffect
会在之后运行。@brianyates-Ivan是对的。从中:
useLayoutEffect
在所有DOM突变后同步激发。使用此选项从DOM读取布局并同步重新渲染。在浏览器有机会绘制之前,useLayoutEffect中计划的更新将同步刷新。尽可能选择标准的
useffect
,以避免阻止视觉更新。“谢谢,伊万!明白。谢谢,先生们。