首页 > 解决方案 > 我希望这个 useRef 和 useEffect 组合会失败……为什么会成功?

问题描述

我希望这useEffect在第一次渲染时会失败,因为我会假设innerCarouselRef.current在第一次渲染时未定义并且它会调用getBoundingClientRect. 为什么它起作用/为什么innerCarouselRef.current在运行时定义useEffect

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

标签: reactjsreact-hooks

解决方案


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

我建议阅读useEffect文档以获得更好的理解。


推荐阅读