typescript RefForwardingComponent 不起作用

IT技术 reactjs typescript tsx
2021-04-11 05:29:41

我试图让我的组件接受一个引用。

我有一个像这样的组件:

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)

我究竟做错了什么?

4个回答

RefForwardingComponent是一个渲染函数,它接收 props 和 ref 参数并返回一个 React 节点 - 它不是组件:

第二个 ref 参数仅在您使用 React.forwardRef 调用定义组件时才存在。常规函数或类组件不接收 ref 参数,并且 ref 在 props 中也不可用。文档

这也是原因,为什么RefForwardingComponent弃用的青睐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} />

您的代码是正确的,但您遗漏了一个小细节。

使用的时候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);

@Warren ,您说得对,问题是编译时类型错误。forwardRef 函数返回的类型是接受 ref 属性的类型。ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>这基本上包装了你的组件接受你的道具(** PropsWithoutRef**)和“ref”道具(RefAttributes
2021-05-23 05:29:41
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,但他还没有做到这一点。
2021-05-29 05:29:41

自定义函数组件不能将 'ref' 作为props。你将不得不给它一个不同的名字。'yourRef',例如将在props对象内。

<MyComponent yourRef={myRef}></MyComponent>

所以要使用 ref props:

const MyComponent: RefForwardingComponent<HTMLDivElement, IMyComponentProps> = (props) => {
return <div ref={props.yourRef}>Hoopla</div>}

或者你可以解构props:

const MyComponent: RefForwardingComponent<HTMLDivElement, IMyComponentProps> = ({yourRef}) => {
return <div ref={yourRef}>Hoopla</div>}
也许我错了,但我认为这RefForwardingComponent应该让您的自定义组件接受 ref?
2021-06-16 05:29:41

我认为这是 React 的类型定义中的一个错误RefForwardingComponent您可以通过向ref?: React.RefObject<HTMLDivElement>props添加解决此问题这将修复您的编译器错误。

试试这个:

type IMyComponentProps = {
    ref?: React.RefObject<HTMLDivElement>
}

我相信这个要求是一个错误,因为它应该由RefForwardingComponent. 把它放在你自己的 props 中意味着 TypeScript 会期望props你函数内参数包含refprops,我认为它不会。不过这不是什么大问题。