请问如何才能让子组件实时地获取到父级容器的宽高呢?

请问如何才能让子组件实时地获取到父级容器的宽高呢?

在我的示例中:
https://codesandbox.io/s/5mf2v6

在我的子组件Testcomp中,我想要只要父级元素改变,我子组件都能马上获得其宽高:
请问如何才能做到呢?

image.png

image.png

阅读 4.7k
6 个回答

得看你获取宽高的具体作用是什麽,单纯只是铺满,还是说是需要去做一些业务处理。
如果单纯只是铺满,用CSS样式即可,width:100%;height:100% 的方式。
如果需要做业务处理,那么就需要看你的父级宽度是如何修改的,是手动键入宽高,还是通过拖拽窗口,最后通过修改手动修改宽高事件或者 useRef 获取 offsetWidthclientWidth 属性拿到容器的宽度,再 props 给子元素具体的宽高。

用Vue的思想看了一下, 可以试一下这个思路:
可以在父组件的内添加一个传递给子组件的参数,将父组件的宽高作为参数传递给子组件。在父组件的注册resize的事件中获取宽高这个进行修改,每次父组件宽高变化时都会将最新的宽高传递给子组件。在子组件内部就可以访问到父组件的宽高了。

怎么个变化法?不受你代码控制的是吧?那就用 ResizeObserver 来监听。

嫌手写麻烦就上 npm 上找找别人封装好的 hooks:

https://www.npmjs.com/search?q=react%20ResizeObserver

能监听到变化了,剩下的就是普通的父子组件通信的事儿了,这个用不着教吧?

可以在 mounted 中获取一次父组件的宽高,然后用原生api监听父组件的更新,再实时获取其宽高

https://segmentfault.com/q/1010000043408540

可能是一个类似的问题,我在回答里写了一个mixin,不知道能不能解决你的问题

把宽高传过去不就可以了,还是说不能传值,必须要字节点自动获取?

const TestComp = (prop) => {
  return <div style={{ height: prop.height, width: prop.width}}>
    this is child
  </div>
}

const App = () => {
  const html = React.useRef(null);
  const [height, setHeight] = React.useState(100);
  const [width, setWidth] = React.useState(100);
  React.useEffect(() => {
    let time = setTimeout(() => {
      setHeight(200);
      setWidth(200);
    }, 2000);
    return () => {
      clearTimeout(time);
    }
  }, []);
  return <div style={{ height: height, width: width, background: '#ddd' }} ref={html}>
    <TestComp width={width} height={height}></TestComp>
  </div>
};

当然可以。这里是一个使用 ResizeObserver 的 React 函数组件示例:

import React, { useRef, useEffect } from 'react';

const Testcomp = () => {
  const parentRef = useRef();
  const resizeObserverRef = useRef();

  useEffect(() => {
    resizeObserverRef.current = new ResizeObserver((entries) => {
      for (let entry of entries) {
        console.log('Width:', entry.contentRect.width);
        console.log('Height:', entry.contentRect.height);
      }
    });

    if (parentRef.current) {
      resizeObserverRef.current.observe(parentRef.current);
    }

    return () => {
      if (resizeObserverRef.current && parentRef.current) {
        resizeObserverRef.current.unobserve(parentRef.current);
      }
    };
  }, []);

  return (
    <div ref={parentRef} className="test-comp">
      Test component
    </div>
  );
};

export default Testcomp;
推荐问题
logo
Microsoft
子站问答
访问
宣传栏