在 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
时才会渲染...
forwardRef
与useCallback
相同,是一个钩子。在forwardRef
中包装函数(或组件)不会自动调用匿名回调。只有在显式渲染组件时才会调用它。
【参考方案1】:
首先,提供的代码示例似乎是来自 React-to-PDF doc page 的两个示例的组合:从类组件调用和从功能组件调用。请注意,从类组件调用时,AgreementForm
应该像这样呈现 <AgreementForm ref=el => (this.componentRef = el) />
。从函数组件调用时,应该像<AgreementForm ref=componentRef />
这样使用。
提供的示例中的代码将不起作用,因为 <AgreementForm userInfo=props.userInfo ref=(el) => (componentRef = el) />
会将 ref (el
) 分配给 componentRef
变量。在下一次渲染时,let componentRef = useRef();
会将 ref 重新分配给 componentRef
变量。所以ReactToPrint
永远不会引用AgreementForm
。它总是会得到undefined/null
。
要解决这个问题,请使用<AgreementForm userInfo=props.userInfo ref=(el) => (componentRef.current = el) />
。必须将组件的 ref 分配给 ref 变量的.current
属性。
这行content=() => componentRef
也应该改成content=() => componentRef.current
以及问题的答案:
-
当
PrintComponent
被渲染时,AgreementForm
被渲染。
PrintComponent
应该由一些更高级别的组件呈现,以便打印工作
如上所述,(el) => (componentRef = el)
行不正确。应该是(el) => (componentRef.current = el)
。此行会将AgreementForm
ref 分配给componentRef.current
,ReactToPrint
可以使用该字母
【讨论】:
谢谢,首先代码工作,出于某种原因。它提供正确的 PDF 打印。你是说 AgreementForm 不是自己渲染的,而是等待 PrintComponent 渲染的?也就是说,没有AgreementForm的双重渲染?我不从更高级别的父级调用 PrintComponent,我从更高级别的父级调用 AgreementForm,它似乎工作。 注意:我从dev.to/ebereplenty/…得到这个sn-p以上是关于在 React 中使用 forwardRef() 渲染的具体内容的主要内容,如果未能解决你的问题,请参考以下文章
在没有道具的 Typescript 中使用 React.forwardRef
我如何使用 jsdoc 注释注释 React.forwardRef 以便智能感知可以显示在底层组件中?
React.forwardRef与useImperativeHandle