微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无需重新加载页面即可测量组件的宽度

如何解决无需重新加载页面即可测量组件的宽度

我正在使用这个钩子来测量一个 div 组件的大小 (https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node):

function useClientRect() {
  const [rect,setRect] = React.useState(null);
  const ref = React.useCallback(node => {
    if (node !== null) {
      setRect(node.getBoundingClientRect());
    }
  },[]);
  return [rect,ref];
}

这是我的组件,简化了。我将它与 React Map GL 一起使用,因为无法以 % 设置视口的宽度。我找不到其他方法来做到这一点... getBoundsForPoints 是一个获取地图视口范围的函数,给定坐标数组和地图宽度(以像素为单位)。

function Mapas(props){  
    const [rect,ref] = useClientRect() 
    useEffect(()=>{
      const coordinates = [some coordinates]
      let new_viewport
      if (rect!==null){ //Here is when sometimes I get rect===null 
        new_viewport = getBoundsForPoints(coordinates,rect.width) 
      } else {
        new_viewport = getBoundsForPoints(coordinates,500)
      }
      setViewport(new_viewport) 
    },[rect]) 

    return (
        <MDBContainer>
            <MDbrow>
              <MDBCol md='12' xl='8'>
                 <div ref={ref}> {/*Elemento referenciado */}
                  <ReactMapGL
                    {...viewport}
                    mapBoxApiAccesstoken='xxx'}
                    mapStyle='xxx'
                    onViewportChange={nextViewport => setViewport({...nextViewport})}
                    >
                  </ReactMapGL>
                </div>
              </MDBCol>
              <MDBCol xl='4' md='12'>
                 Other stuff
              </MDBCol>
            </MDbrow>       
      </MDBContainer>        
    )
}

export default Mapas

页面加载时它工作正常;但是,当我从其他组件进入页面时,无需重新渲染,rect 为空。我怎样才能避免这种情况,谢谢!

解决方法

import ResizeObserver from 'resize-observer-polyfill';

const measureSize = el => {
    return {
      height: el && el.current && Math.round(el.current.getBoundingClientRect().height),width: el && el.current && Math.round(el.current.getBoundingClientRect().width),};
  };
  const [size,setSize] = useState(measureSize(ref));

  useEffect(() => {
    setSize(measureSize(ref));

    const observer = new ResizeObserver(() => {
      window.requestAnimationFrame(() => {
        setSize(measureSize(ref));
      });
    });
    observer.observe(ref.current);

    return () => {
      observer.disconnect();
    };
  },[ref]);

我使用 polyfill resize-observer-polyfill 来获得更强大的解决方案

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。