打字稿RefForwardingComponent不起作用
Posted
技术标签:
【中文标题】打字稿RefForwardingComponent不起作用【英文标题】:Typescript RefForwardingComponent not working 【发布时间】:2020-03-18 09:01:48 【问题描述】:我正在尝试让我的组件接受 ref。
我有一个这样的组件:
const MyComponent: RefForwardingComponent<htmlDivElement, IMyComponentProps> = (props, ref) =>
return <div ref=ref>Hoopla</div>
但是当我尝试将 ref 传递给时是这样的:
<MyComponent ref=myRef></MyComponent>
...我收到此错误:
Property 'ref' does not exist on type 'IntrinsicAttributes & IMyComponentProps & children?: ReactNode; '.ts(2322)
我做错了什么?
【问题讨论】:
【参考方案1】:RefForwardingComponent
是一个render function,它接收 props 和 ref 参数并返回一个 React 节点 - 它是 no 组件:
第二个 ref 参数仅在您使用 React.forwardRef 调用定义组件时存在。常规函数或类组件不接收 ref 参数,并且 ref 在 props 中也不可用。 (docs)
这也是为什么RefForwardingComponent
是deprecated 而支持ForwardRefRenderFunction
的原因,这在功能上是等效的,但名称不同以使区别更清晰。
您使用React.forwardRef
将渲染函数转换为接受 refs 的实际组件:
import React, ForwardRefRenderFunction from 'react'
type IMyComponentProps = a: string
const MyComponentRenderFn: ForwardRefRenderFunction<HTMLDivElement, IMyComponentProps> =
(props, ref) => <div ref=ref>Hoopla</div>
const MyComponent = React.forwardRef(MyComponentRenderFn);
const myRef = React.createRef<HTMLDivElement>();
<MyComponent a="foo" ref=myRef />
【讨论】:
【参考方案2】:您的代码是正确的,但您遗漏了一个小细节。
使用RefForwardingComponent
时需要导出forwardRef
包裹的组件
import React, forwardRef, RefForwardingComponent from 'react';
type IMyComponentProps =
const MyComponent: RefForwardingComponent<HTMLDivElement, IMyComponentProps> = (props, ref) =>
return <div ref=ref>Hoopla</div>
export default forwardRef(MyComponent);
【讨论】:
OP 的问题是编译时类型错误。forwardRef
不会修复它。缺少forwardRef
最终会导致运行时错误:Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
。所以 OP 确实需要 forwardRef,但他还没有做到那么远。
@Warren,你说得对,问题是编译时类型错误。 forwardRef 函数返回的类型是接受 ref 属性的类型。 ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>
这基本上包装了你的组件接受你的道具 (** PropsWithoutRef**) 和 'ref' 道具 (RefAttributes)【参考方案3】:
自定义函数组件不能将 'ref' 作为道具。你将不得不给它一个不同的名字。例如,'yourRef' 将在 props 对象内。
<MyComponent yourRef=myRef></MyComponent>
所以要使用 ref 属性:
const MyComponent: RefForwardingComponent<HTMLDivElement, IMyComponentProps> = (props) =>
return <div ref=props.yourRef>Hoopla</div>
或者你可以分解道具:
const MyComponent: RefForwardingComponent<HTMLDivElement, IMyComponentProps> = (yourRef) =>
return <div ref=yourRef>Hoopla</div>
【讨论】:
也许我弄错了,但我认为RefForwardingComponent
是假设让您的自定义组件接受参考?【参考方案4】:
我认为这是 React 的 RefForwardingComponent
类型定义中的一个错误。您可以通过将 ref?: React.RefObject<HTMLDivElement>
添加到您的道具来解决此问题。这将修复您的编译器错误。
试试这个:
type IMyComponentProps =
ref?: React.RefObject<HTMLDivElement>
我认为这个要求是一个错误,因为它应该由RefForwardingComponent
为您添加到道具中。把它放在你自己的道具中意味着 TypeScript 会期望你的函数中的 props
参数包含 ref
道具,我认为它不会。不过这不是什么大问题。
【讨论】:
以上是关于打字稿RefForwardingComponent不起作用的主要内容,如果未能解决你的问题,请参考以下文章