在 React 中使用 forwardRef() 渲染的具体内容

Posted

技术标签:

【中文标题】在 React 中使用 forwardRef() 渲染的具体内容【英文标题】:What specifically gets rendered with forwardRef() in React 【发布时间】:2022-01-24 01:35:00 【问题描述】:

我有以下从另一个来源获得的 sn-p。我有一个名为AgreementForm 的主要功能组件,它需要支持插件React-to-Print 提供的Print-to-PDF 功能。这样做的方法是将AgreementForm“包装”在forwardRef 中,并将其传递给它之后定义的下一个组件,即React-to-Print 组件。 sn-p 工作正常,但我不明白它的作用,

我的问题是,

AgreementForm 会自己渲染吗?

如果不是,谁定义PrintComponent 随时​​被渲染,而不是 AgreementForm

(el) => (componentRef = el) 表达式有什么作用?

 export const AgreementForm = React.forwardRef((props, ref) => 
       // State vars...
       const [myVar, setMyVar] = useState(null);
       // useEffects...
       useEffect(() =>  
       , [myVar]);
       // Render...
       return (
          <>...</>
       );

  // This is print component to wrap the print button and content.
  export default function PrintComponent(props) 
     let componentRef = useRef();

     return (
     <>
      <div>
          <ReactToPrint 
              trigger=() => <Button style='margin-bottom':'15px'>Print</Button>
              content=() => componentRef
          />

        /* component to be printed */
        <AgreementForm userInfo=props.userInfo ref=(el) => (componentRef = el) />
      </div>
    </>
  );
 

【问题讨论】:

所以他们得到渲染?表单和打印组件? 是的,他们有。只有 PrintComponent 从 Form 接收引用。 所以我的表单被渲染了 两次 ?错了,应该只有 1 个实例。 不,它不会被渲染两次AgreementForm 仅在渲染 PrintComponent 时才会渲染... forwardRefuseCallback 相同,是一个钩子。在forwardRef 中包装函数(或组件)不会自动调用匿名回调。只有在显式渲染组件时才会调用它。 【参考方案1】:

首先,提供的代码示例似乎是来自 React-to-PDF doc page 的两个示例的组合:从类组件调用和从功能组件调用。请注意,从类组件调用时,AgreementForm 应该像这样呈现 &lt;AgreementForm ref=el =&gt; (this.componentRef = el) /&gt; 。从函数组件调用时,应该像&lt;AgreementForm ref=componentRef /&gt;这样使用。

提供的示例中的代码将不起作用,因为 &lt;AgreementForm userInfo=props.userInfo ref=(el) =&gt; (componentRef = el) /&gt; 会将 ref (el) 分配给 componentRef 变量。在下一次渲染时,let componentRef = useRef(); 会将 ref 重新分配给 componentRef 变量。所以ReactToPrint 永远不会引用AgreementForm。它总是会得到undefined/null

要解决这个问题,请使用&lt;AgreementForm userInfo=props.userInfo ref=(el) =&gt; (componentRef.current = el) /&gt;。必须将组件的 ref 分配给 ref 变量的.current 属性。

这行content=() =&gt; componentRef也应该改成content=() =&gt; componentRef.current

以及问题的答案:

    PrintComponent 被渲染时,AgreementForm 被渲染。 PrintComponent 应该由一些更高级别的组件呈现,以便打印工作 如上所述,(el) =&gt; (componentRef = el) 行不正确。应该是(el) =&gt; (componentRef.current = el)。此行会将AgreementForm ref 分配给componentRef.currentReactToPrint 可以使用该字母

【讨论】:

谢谢,首先代码工作,出于某种原因。它提供正确的 PDF 打印。你是说 AgreementForm 不是自己渲染的,而是等待 PrintComponent 渲染的?也就是说,没有AgreementForm的双重渲染?我不从更高级别的父级调用 PrintComponent,我从更高级别的父级调用 AgreementForm,它似乎工作。 注意:我从dev.to/ebereplenty/…得到这个sn-p

以上是关于在 React 中使用 forwardRef() 渲染的具体内容的主要内容,如果未能解决你的问题,请参考以下文章

在没有道具的 Typescript 中使用 React.forwardRef

React中React.forwardRef的使用方式

我如何使用 jsdoc 注释注释 React.forwardRef 以便智能感知可以显示在底层组件中?

React.forwardRef与useImperativeHandle

[react] 什么是React.forwardRef?它有什么作用?

带有 React.forwardRef 功能组件的 VSCode TS 错误