[英]React Tooltip component with TypeScript getting a 'Possibly Undefined' error on my useRef element, not sure how to fix
I have a simple functional React component for a re usable tooltip that I'm working on and I've got everything almost ready to test, but I'm getting a TypeScript error 'Possibly Undefined' on my useRef element node
at this line in my function: if (node.current.contains(target))...
and I don't know how to fix it.我有一个简单的功能性 React 组件,用于我正在处理的可重用工具提示,我已经准备好测试所有内容,但是我在这一行的 useRef 元素
node
上收到 TypeScript 错误“可能未定义”我的 function: if (node.current.contains(target))...
我不知道如何解决它。
I initially tried setting the type of useRef as:我最初尝试将 useRef 的类型设置为:
const node = useRef()<HTMLDivElement>(null);
and then calling it in my function like:然后在我的 function 中调用它,例如:
const handleHover = ({ target }) => {
if (node?.current.contains(target)) {
....
}
}
But that throws an error "Cannot invoke an expression whose type lacks a call signature. Type 'MutableRefObject' has no compatible call signatures."但这会引发错误“无法调用类型缺少调用签名的表达式。类型'MutableRefObject'没有兼容的调用签名。” at the definition level and then "Expected an expression" in my function.
在定义级别,然后在我的 function 中“预期一个表达式”。
I'm certain the answer is obvious and I have just been staring at this for too long but I'm stumped at the current moment so any feedback is hugely appreciated.我确信答案是显而易见的,我已经盯着这个太久了,但我现在很难过,所以非常感谢任何反馈。
My current component for full reference:我当前的完整参考组件:
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;
You can solve this by typing the ref as follows (using your example):您可以通过键入以下引用来解决此问题(使用您的示例):
const node = useRef() as MutableRefObject<HTMLDivElement>;
Just be sure you have the necessary imports as well:只要确保您也有必要的导入:
import React, { useRef, MutableRefObject } from 'react';
You are almost there but there are two syntactical errors.您快到了,但有两个语法错误。
const node = useRef()<HTMLDivElement>(null);
useRef()
calls the function and then you call the result of that function with (null)
. useRef()
调用 function 然后用(null)
调用 function 的结果。 You need to remove those first parentheses and just call the hook once:您需要删除那些第一个括号,只需调用一次钩子:
const node = useRef<HTMLDivElement>(null);
if (node?.current.contains(target)) {
The variable node
is always defined.始终定义变量
node
。 It is the current
property which might be null
.它是
current
属性,可能是null
。 So move the optional chaining question mark to after current
:所以将可选的链接问号移到
current
之后:
if (node.current?.contains(target)) {
If you want to add a type to the arguments of handleHover
there's a minor issue because the target
property of a MouseEvent
is either EventTarget
or null
.如果您想向 handleHover 的
handleHover
添加类型,则存在一个小问题,因为MouseEvent
的target
属性是EventTarget
或null
。 But .contains()
expects a Node
.但是
.contains()
需要一个Node
。 I'm not sure if you would treat invalid arguments as "hover over" or "hover out".我不确定您是否会将无效的 arguments 视为“悬停”或“悬停”。 It's unlikely to occur in reality but to be type-safe we should check it.
它在现实中不太可能发生,但为了类型安全,我们应该检查它。
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);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.