如何将 ref 作为组件对象中的 prop 传递?

How to pass ref as a prop in object of component?

我正在访问 availableWidgets 作为 GridItem 中的 widget?.component 以迭代组件,但现在我想将 GridItem Ref 传递给小部件组件。 你有什么建议给我。

const availableWidgets = [
  {},
  {
    component: <DashboardsGuide />,
    id: "1"
  },

  {
    component: <DashboardsWeather />,
    id: "2"
  },
  {
    component: <DashboardsTraining />,
    id: "3"
  },
];

在这里,可用的小部件包含组件,我想将父 ref.current 传递给这个小部件,但我不知道如何在迭代时将 ref 传递给它的子组件。

如果可以的话请多多指教

我曾尝试 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}
    >
      {console.log(ref?.current?.offsetHeight, ref?.current?.offsetWidth)}
      {widget?.component}
      {children}
    </div>
  );
});

我正在使用 React Grid 布局库。

function GridLayout({ layouts, toggle }) {
  return (
    <ResponsiveGridLayout
      // className="layout"
      layouts={layouts}
      rowHeight={20}
      isDraggable={toggle ? true : false}
      isResizable={toggle ? true : false}
      margin={[20, 20]}
      onLayoutChange={(...e) => {
        localStorage.setItem("layouts", JSON.stringify(e[1]));
      }}
      breakpoints={{ lg: 1280, md: 992, sm: 767, xs: 480, xxs: 0 }}
      cols={{ lg: 24, md: 20, sm: 12, xs: 8, xxs: 4 }}
    >
      {layouts.lg.map((item) => (
        <GridItem id={item.i} key={item.i} widget={availableWidgets[item.i]} />
      ))}
    </ResponsiveGridLayout>
  );
}

通过使用

{layouts.lg.map((item) => (
    <GridItem id={item.i} key={item.i} widget={availableWidgets[item.i]} />
  ))}

我正在迭代小部件

如果我理解正确,GridItem 需要创建一个 React ref 并将其附加到正在呈现的 div,然后将 ref 传递给子小部件组件以访问当前(即偏移量)的值。

为此,我建议对 availableWidgets 数组进行一些小改动,以便您可以在渲染时将组件实例化为 JSX,然后注入任何道具。

const availableWidgets = [
  {},
  {
    component: DashboardsGuide,
    id: "1"
  },

  {
    component: DashboardsWeather,
    id: "2"
  },
  {
    component: DashboardsTraining,
    id: "3"
  },
];

接下来 GridItem 创建 React ref,将其附加到 div 并实例化小部件组件以在 prop 中传递 ref。

const GridItem = ({
  className,
  style,
  children,
  item,
  widget = {},
  id,
  ...rest
}) => {
  // (1) Create a React ref
  const gridItemRef = React.useRef();

  // (3) get widget component and rename to valid PascalCase name
  const { component: Widget } = widget;

  // Log the ref values in an intentional side-effect
  React.useEffect(() => {
    const { offsetHeight, offsetWidth } = gridItemRef.current;
    console.log(offsetHeight, offsetWidth);
  });

  return (
    <div
      id={`width-height-${id}`}
      className={`grid-item ${className}`}
      style={style}
      ref={gridItemRef} // (2) attach ref
      {...rest}
    >
      {Widget && <Widget gridItemRef={gridItemRef} />} // (4) render Widget and pass ref prop
      {children}
    </div>
  );
};

在每个小部件组件(DashboardsGuideDashboardsWeatherDashboardsTraining)中,通过 props 访问传递的 GridItemgridItemRef