带有TypeScript的React Tooltip组件在我的useRef元素上收到"可能未定义"错误,不确定如何修复



我有一个简单的函数React组件,用于我正在处理的可重复使用的工具提示,我已经准备好了测试的一切,但我在函数if (node.current.contains(target))...的这一行,在我的useRef元素node上收到了一个TypeScript错误"可能未定义",我不知道如何修复它。

我最初尝试将useRef的类型设置为:

const node = useRef()<HTMLDivElement>(null);

然后在我的函数中调用它,比如:

const handleHover = ({ target }) => {
if (node?.current.contains(target)) {
....
}
}

但这会在定义级别引发错误"无法调用类型缺少调用签名的表达式。类型"MutableRefObject"没有兼容的调用签名。",然后在我的函数中引发错误"Expected a expression"。

我确信答案是显而易见的,我只是盯着这个看了太久了,但我现在被难住了,所以我们非常感谢任何反馈。

我的当前组件供完全参考:

import React, { useEffect, useRef, useState } from 'react';
import './tooltip-style.scss'
import cx from 'classnames';

type Props = {
title: string;
position: string;
children: React.ReactNode;
};
const Tooltip = (props: Props) => {
const { title, position, children } = props;
const node = useRef();
const [isVisible, setState] = useState(false);
const handleHover = ({ target }) => {
if (node.current.contains(target)) {
// hover over
return;
}
// hover out
setState(false);
};
useEffect(() => {
document.addEventListener('mouseover', handleHover);
return () => {
document.removeEventListener('mouseout', handleHover);
};
}, []);
return (
<div className={'.container'}
data-testid="tooltip"
ref={node}
onMouseEnter={() => setState(!isVisible)}
>
<div data-testid="tooltip-placeholder">{children}</div>
{isVisible && (
<div
className={cx('.tooltipContent', [position])}
data-testid="tooltip-content"
>
<span className={'.arrow'}></span>
{title}
</div>
)}
</div>
);
};

export default Tooltip;

您可以通过如下方式(使用您的示例(键入ref来解决此问题:

const node = useRef() as MutableRefObject<HTMLDivElement>;

只要确保你也有必要的进口:

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

您已接近目标,但存在两个语法错误。

const node = useRef()<HTMLDivElement>(null);

useRef()调用该函数,然后用(null)调用该函数的结果。你需要去掉第一个括号,只调用钩子一次:

const node = useRef<HTMLDivElement>(null);

if (node?.current.contains(target)) {

始终定义变量node。它是current属性,可能是null。因此,将可选的链接问号移到current:之后

if (node.current?.contains(target)) {

如果要向handleHover的参数添加类型,则会出现一个小问题,因为MouseEventtarget属性是EventTargetnull。但是.contains()期望Node。我不确定你是否会把无效的论点视为";悬停在";或";悬停在外";。它不太可能在现实中发生,但为了类型安全,我们应该检查它。

const node = useRef<HTMLDivElement>(null);
const [isVisible, setState] = useState(false);
const handleHover = ({ target }: MouseEvent) => {
if (target instanceof Node && node.current?.contains(target)) {
// hover over
return;
}
// hover out
setState(false);
};

打字游戏场链接

最新更新