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

Posted

技术标签:

【中文标题】如何将 ref 作为组件对象中的道具传递?【英文标题】:How to pass ref as a prop in object of component? 【发布时间】:2022-01-07 18:31:21 【问题描述】:

我在 GridItem 中以 widget?.component 的形式访问 availableWidgets 以迭代组件,但现在我想将 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 Layout 库。

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] />
  ))

我正在迭代小部件

【问题讨论】:

您对availableWidgets 对象形状有任何控制权吗?换句话说,component 需要是 JSX 吗?可以是你要渲染的组件的引用吗? 请检查我的更新代码 您只是想通过GridItem 将React ref 传递给div 元素还是小部件组件?参考在哪里创建/生成? 我想将 GridItem ref 传递给小部件组件.. 所以我可以访问小部件组件中的 GridItem 偏移属性 那么GridItem 是否需要创建 ref 才能传递给 widget 组件? 【参考方案1】:

如果我理解正确,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

【讨论】:

应该有一些小的修改,因为我想将 gridItemRef 传递给 DashboardsGuide、DashboardsWeather、DashboardsTraining 组件,它将根据 ...... layouts.lg.map((item) => ( )) @HarshMendapara 你能为我澄清一下评论吗? AFAIK 您的询问和讨论的行为,gridItemRef 被传递给这些组件。 当然,根据您的解决方案小部件组件将接收 ref 作为道具,但我想将 ref 从 GridItem 组件传递到 DashboardsGuide、DashboardsWeather、DashboardsTraining 组件 @HarshMendapara 这些来自availableWidgetsDashboardsGuideDashboardsWeatherDashboardsTraining 组件,现在在运行时计算。 ? @HarshMendapara 希望Choosing the type as runtime 说明这里发生了什么。 widget=availableWidgets[item.i] availableWidgets[item.i] 可能是这些仪表板组件之一,通过 widget 属性传递。在GridItem const component: Widget = widget; 正在访问component 属性以引用仪表板组件并将其重命名为Widget,因此它是一个有效的React组件名称,然后将其呈现为JSX并将无关的道具传递给它.

以上是关于如何将 ref 作为组件对象中的道具传递?的主要内容,如果未能解决你的问题,请参考以下文章

如何将对象数组作为道具传递给组件,然后将数组的成员作为道具传递给嵌套组件?

如何将一个道具作为变量传递给 React 中的另一个道具?

如何将从数据库接收到的数据作为道具传递给 Reactjs 中的另一个组件

如何将组件中的道具传递给 FlatList renderItem

如何将道具传递给vue中的子组件

为啥数组中的两个对象中只有一个作为道具传递?