You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何将GridItem的ref作为prop传递给对象内存储的组件?

你之前实现失败的核心原因是 availableWidgets 中存储的是已经实例化完成的React元素(比如 <DashboardsGuide /> 是已经调用渲染后的结果),无法再给这类预渲染的元素追加props或ref。按照下面的方案修改即可实现需求:


第一步:重构availableWidgets结构

把存储预渲染元素改为存储组件本身,方便后续动态传参:

const availableWidgets = [
  {},
  {
    component: DashboardsGuide, // 去掉< />,存组件引用
    id: "1"
  },
  {
    component: DashboardsWeather,
    id: "2"
  },
  {
    component: DashboardsTraining,
    id: "3"
  },
];

第二步:选择合适的传值方案

根据你的需求可以选以下三种方案中的任意一种:

方案1:普通prop传递ref(最简方案,无需修改子组件定义)

直接把GridItem的ref作为普通prop传给子组件,不需要用forwardRef包裹子组件:

const GridItem = React.forwardRef(function GridItem(
  { className, style, children, item, widget, id, ...rest },
  ref
) {
  return (
    <div
      id={`width-height-${id}`}
      className={`grid-item ${className}`}
      style={style}
      ref={ref}
      {...rest}
    >
      {/* 动态渲染组件,把ref作为普通prop传入 */}
      {widget?.component && <widget.component gridItemRef={ref} />}
      {children}
    </div>
  );
});

子组件中直接通过props访问即可,注意要在useEffect里读取ref.current(保证DOM已经挂载):

// 子组件示例
function DashboardsGuide({ gridItemRef }) {
  useEffect(() => {
    if (gridItemRef.current) {
      console.log("GridItem宽度:", gridItemRef.current.offsetWidth);
      console.log("GridItem高度:", gridItemRef.current.offsetHeight);
    }
  }, [gridItemRef]);

  return <div>组件内容</div>
}

方案2:符合React规范的ref传递(用forwardRef)

如果需要遵循React的ref传递规范,可以用forwardRef包裹所有widget子组件:

// 子组件用forwardRef包裹
const DashboardsGuide = React.forwardRef((props, ref) => {
  useEffect(() => {
    if (ref.current) {
      console.log("GridItem宽度:", ref.current.offsetWidth);
    }
  }, [ref]);
  return <div>组件内容</div>
});

GridItem中直接把ref传给子组件即可:

{widget?.component && <widget.component ref={ref} />}

方案3:仅传递宽高(更安全,无需暴露完整DOM节点)

如果子组件只需要GridItem的尺寸信息,不需要完整DOM引用,可以直接监听尺寸变化后传宽高值:

const GridItem = React.forwardRef(function GridItem(
  { className, style, children, item, widget, id, ...rest },
  ref
) {
  const [gridSize, setGridSize] = useState({ width: 0, height: 0 });

  useEffect(() => {
    if (!ref.current) return;
    // 初始化尺寸
    const updateSize = () => {
      setGridSize({
        width: ref.current.offsetWidth,
        height: ref.current.offsetHeight
      });
    };
    updateSize();
    // 监听GridItem尺寸变化(拖拽/缩放时自动更新)
    const resizeObserver = new ResizeObserver(updateSize);
    resizeObserver.observe(ref.current);
    return () => resizeObserver.disconnect();
  }, [ref]);

  return (
    <div
      id={`width-height-${id}`}
      className={`grid-item ${className}`}
      style={style}
      ref={ref}
      {...rest}
    >
      {widget?.component && <widget.component gridSize={gridSize} />}
      {children}
    </div>
  );
});

子组件直接读取props.gridSize即可拿到实时宽高,无需处理ref判断。


内容的提问来源于stack exchange,提问作者Harsh Mendapara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 03:45:10