water
water

Reputation: 333

getBoundingClientRect().width return 0 use react hooks

I generally use getBoundingClientRect().width when developing a Swiper Component using react hooks, but in some examples getBoundingClientRect().width return 0.

  useEffect(() => {
    const width = containerWrap.current.getBoundingClientRect().width;
    console.log(containerWrap.current.getBoundingClientRect().width)  // 0
    console.log(document.body.getBoundingClientRect().width);         // 750
    // it works well
    // setTimeout(() => {
    //   console.log(containerWrap.current.getBoundingClientRect().width)  // 750
    // }, 0)
    setSwiperWidth(width);
    if (selectedIndex >= count) {
      active.current = 0;
    }
    setSwipeStyle({...swipeStyle, transform: `translate3d(-${width * (selectedIndex >= count ? 1 : (selectedIndex + 1))}px, 0, 0)`, width: ((count + 2) * width) + 'px'})
    return () => {
      containerWrap.current.remove();
    }
  }, [])

I use setTimeout in useEffect function , It works well;

the simple swiper code demo is here:

simple swiper demo code

Upvotes: 3

Views: 3542

Answers (2)

grreeenn
grreeenn

Reputation: 2545

Just to examplify the great @ljbc1994's answer:

    const ref = useRef(null);
    const [refElementWidth, setRefElementWidth] = useState(0);
    useLayoutEffect(() => {
        if (ref.current) {
            setRefElementWidth(ref.current.getBoundingClientRect().width);
        }
    });

Upvotes: 1

ljbc1994
ljbc1994

Reputation: 2244

You need to use useLayoutEffect to get layout changes as it fires after all DOM mutations have been performed.

Reference: https://reactjs.org/docs/hooks-reference.html#uselayouteffect

Upvotes: 8

Related Questions