首页 > 解决方案 > React 获取 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 组件确实返回了一个 ChartCanvas 对象react-stockcharts,它需要一个宽度和高度(没有它它不会占用 div 的整个空间)

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

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

我能得到一些帮助吗?

标签: reactjstypescriptreact-hooksreact-grid-layout

解决方案


“从不”类型上不存在属性“宽度”

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

An实际上没有HTMLDivElement and.width.height但您可以使用.clientWidthor.offsetWidth代替。

const canvasRef = useRef<HTMLDivElement>(null);

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

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

解决这个问题的最简单方法是添加另一层嵌套。将ResponsiveReactGridLayout在最外层设置一个 ref div,但您可以在其中添加另一个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说明使用。

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

const ResponsiveReactGridLayout = WidthProvider(Responsive);

CodeSandbox 演示


推荐阅读