typescript useRef类型脚本-无法分配给类型LegacyRef< HTMLDivElement>

djmepvbi  于 2023-01-14  发布在  TypeScript
关注(0)|答案(7)|浏览(364)

我正在尝试使用useRef与TypeScript,但遇到了一些麻烦。
对于我的RefObject(我假设),我需要访问current。(即node.current
我尝试了以下方法

  • const node: RefObject<HTMLElement> = useRef(null);
  • const node = useRef<HTMLElement | null>(null);

但是当我设置ref时,我总是被告知X is not assignable to type 'LegacyRef<HTMLDivElement> | undefined'.
return <div ref={ node }>{ children }</div>
编辑:这不应该被限制为任何一种类型的元素,所以不仅仅是HTMLDivElement | HTMLFormElement | HTMLInputElement
编辑:这应该可以作为一个示例

import React, { useRef, RefObject } from 'react';

function Test() 
{
    // const node = useRef(null);
    // const node: RefObject<HTMLElement> = useRef(null);
    const node = useRef<HTMLElement | null>(null);

    if (
        node &&
        node.current &&
        node.current.contains()
    ){ console.log("current accessed")}

    return <div ref={ node }></div>
}
suzh9iv8

suzh9iv81#

以上这些对我都不起作用,但事实证明解决办法相当简单...
我所做的错误是没有显式地将“null”作为参数包含在useRef初始化中(它需要null,而不是未定义)。此外,您不能使用“HTMLElement”作为您的ref类型,您必须更具体,所以对我来说,它是“HTMLDivElement”的例子)。
我的工作代码是这样的:

const ref = useRef<HTMLDivElement>(null);

return <div ref={ref}> Some Content... </div>
yhxst69z

yhxst69z2#

只需导入React:

import React, { useRef } from 'react';

function Test() {
    const node = useRef<HTMLDivElement>(null);

    if (
        node &&
        node.current &&
        node.current.contains()
    ){ console.log("current accessed")}

    return <div ref={node}></div>
}

我做了一个更新。使用HTMLDivElement作为泛型参数,而不是HTMLElement | null。另外,contains需要一个参数。

UPDATEuseRef需要DOM元素类型的泛型参数。您不需要使用| null,因为RefObject已经知道current可能为null。

参见下一类型:

interface RefObject<T> {
  readonly current: T | null
}

TS & React足够聪明,能够判断出您的ref可能为空

jutyujz0

jutyujz03#

我来这里寻求iframe引用的帮助。也许这个解决方案将帮助其他正在寻找相同东西的人。我用HTMLIFrameElement替换了HTMLDivElement,所以:

const node = useRef<HTMLIFrameElement>(null);
disho6za

disho6za4#

<svg>元素也是如此:

const ref = useRef<SVGSVGElement>(null)
...
<svg ref={ref} />
mlnl4t2r

mlnl4t2r5#

selfref = React.createRef<HTMLInputElement>()

我给予了精确的TS类型,然后编辑器通过了检查。现在它工作得很好。

i7uaboj4

i7uaboj46#

关键是使用HTMLElement和undefined进行初始化

const node = useRef<HTMLElement>();
lyr7nygr

lyr7nygr7#

看完所有答案后,我不确定其中任何一个是否能完全回答/解释问题。在这种情况下,问题有两个方面:

  • 我们需要使用不同的HTML界面对象-〉HTMLDivElement
  • 我们需要将默认值传递给引用初始化

React useRef 函数实际上有3个不同的签名(在React 16.8中):
如果传递的默认值与泛型类型的类型相同

function useRef\<T>(initialValue: T): MutableRefObject<T>;

如果我们传递一个与泛型类型OR null相同类型的默认值(如这里的许多响应所示)

function useRef\<T>(initialValue: T|null): RefObject<T>;

如果不传递默认值AND/OR,则不传递泛型类型

function useRef\<T = undefined>(): MutableRefObject<T | undefined>;

真实的的问题归结为 MutableRefObjectLegacyRef 的不兼容性。我猜React团队对引用的数据类型进行了更改,因此我们有多个签名和基于我们传递的引用类型。
从react eslint得到一个更好的错误消息是很好的,至少我们得到的通用TS错误消息不足以立即发现错误。
Tl;dr:在 useRef 对象中传递 null 作为默认值将给予同时满足 MutableRefObjectLegacyRef(可能)的引用对象

相关问题