简体   繁体   English

React Tooltip 组件与 TypeScript 在我的 useRef 元素上出现“可能未定义”错误,不知道如何修复

[英]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添加类型,则存在一个小问题,因为MouseEventtarget属性是EventTargetnull 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);
};

Typescript Playground Link Typescript 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 react 和 typescript 修复错误 object 可能未定义? - How to fix the error object could be possibly undefined using react and typescript? 在 react-js 中的 useRef() 上出现未定义的错误 - getting undefined error on useRef() in react-js 反应 typescript state Object 可能是“未定义”错误 - react typescript state Object is possibly 'undefined' error 使用反应挂钩 (useRef) 将 class 组件转换为功能组件—如何避免“未定义”错误 - Converting class component to functional component using react hooks (useRef)—how to avoid “undefined” error 如何使用 react 和 typescript 修复 object 可能是可重用组件中未定义的错误? - How to fix the object is probably undefined error within a reusable component using react and typescript? 打字稿抱怨反应组件可选道具可能未定义 - Typescript complains that react component optional prop could possibly be undefined Object 可能是“空”:TypeScript,React useRef & Formik innerRef - Object is possibly 'null': TypeScript, React useRef & Formik innerRef 如何使用 react 和 typescript 修复错误无法读取未定义的属性? - How to fix error cannot read property of undefined using react and typescript? 在 Canvas 上反应 useRef 得到 null 或 undefined - React useRef on Canvas getting null or undefined 如何修复“对象可能未定义”? - How to fix “Object is possibly undefined”?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM