React 获取 ResponsiveReactGridLayout 中父元素的大小

React get size of parent element within ResponsiveReactGridLayout

我正在尝试使用 ResponsiveReactGridLayout 呈现仪表板,我在功能组件中的代码如下:


const Home = () => {
  const [coins, setCoins] = useState(latestCoins);
  const [coin, setCoin] = useState(curCoin);
  const canvasRef = useRef(null);

  useEffect(() => {
    getCoins().then((data) => setCoins(data));
  }, []);
  return (
    <ResponsiveReactGridLayout
      onResize={(e) => console.log(e)}
      className="layout"
      layouts={layouts}
      rowHeight={100}
      breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
      cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
    >
     
      <div key="candlestick" className="home-card" ref={canvasRef}>
        {console.log(canvasRef)}
        //Trying to use canvasRef.current.width and height but getting an error: Property 'width' does not exist on type 'never'
        <Candlestick coin={coin} width={600} height={400} />
      </div>
    </ResponsiveReactGridLayout>
  );
};

我的 Candlestick 组件 return 来自 react-stockcharts 的 ChartCanvas 对象,它需要一个宽度和高度(没有它它不会占用 [=24] 的整个 space =])

如何从 div 获取高度和宽度?

我试过使用 useRef() 挂钩,但它似乎总是将 current 设置为 null。

我能得到一些帮助吗?

您可能会在初始加载时将其视为未定义,请在此处使用此可选语句

canvasRef?.current?.width

如果您有任何默认值,您可以使用 Nullish coalescing 以及默认值

canvasRef?.current?.width?? default_value

然后就是下面这样

 <Candlestick coin={coin} width={canvasRef?.current?.width?? default_width} height={canvasRef?.current?.height ?? default_Height} />

Property 'width' does not exist on type 'never'

这实际上是一个 TypeScript 错误。这意味着 TypeScript 不知道 .current 属性 的类型应该是什么。因此它不知道 .current 具有属性 .width.height 并且它会阻止您访问它们。您需要告诉 TypeScript 这是对 div.

的引用

一个HTMLDivElement其实其实没有.width.height,但是你可以用.clientWidth.offsetWidth 代替。

const canvasRef = useRef<HTMLDivElement>(null);

I've tried using the useRef() hook, but it always seems to have current as null.

ResponsiveReactGridLayout 组件在其子组件上设置自己的引用,因此您的 ref={canvasRef} 被覆盖。

解决这个问题的最简单方法是添加另一层嵌套。 ResponsiveReactGridLayout 将在最外面的 div 上设置一个 ref,但您可以在其内部添加另一个 div,并使用您控制的 ref。确保它填满整个高度。

请注意,.current 属性 在第一次渲染时可能仍然是 null。您可以使用默认值,如@PushpikaWan 所建议的那样,或者您可以延迟渲染图表,直到获得实际宽度。

<ResponsiveReactGridLayout /*...props...*/ >
    <div key="candlestick" className="box">
        <div ref={canvasRef} style={{ width: "100%", height: "100%" }}>
            {canvasRef.current ? (
                <Candlestick
                    data={data}
                    width={canvasRef.current.clientWidth}
                    height={canvasRef.current.offsetHeight}
                />
            ) : null}
        </div>
    </div>
    /*...other children...*/
</ResponsiveReactGridLayout>

我需要在网格布局上添加明确的 width 才能使其正常工作。我不确定你是否已经在做这部分,但你可以使用 WidthProvider 解释 in the docs.

import { Responsive, WidthProvider } from 'react-grid-layout';

const ResponsiveReactGridLayout = WidthProvider(Responsive);

CodeSandbox Demo