未捕获的类型错误:无法读取 HTMLDocument.handler 处的 null 属性“包含”

时间:2021-04-05 19:36:49

标签: javascript reactjs

我的 Header 组件中有以下代码。我认为这可能会引发此错误,因为我什至在它呈现在屏幕上之前就尝试访问它。我不确定为什么这不起作用,我曾尝试在子组件中使用 forwardRef,但在 SearchDropDown 组件的 ref 中出现以下错误。我希望有人能告诉我这里出了什么问题。

Type '((instance: unknown) => void) | MutableRefObject<unknown>' is not assignable to type 'LegacyRef<HTMLDivElement>'.
  Type 'MutableRefObject<unknown>' is not assignable to type 'LegacyRef<HTMLDivElement>'.
    Type 'MutableRefObject<unknown>' is not assignable to type 'RefObject<HTMLDivElement>'.
      Types of property 'current' are incompatible.
        Type '{}' is missing the following properties from type 'HTMLDivElement': align, addEventListener, removeEventListener, accessKey, and 235 more.
The expected type comes from property 'ref' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'

页面组件

  const domNodeRef = useRef(null);
  const [search, setSearch] = useState("");

  useEffect(() => {
    const handler = (e) => {
      if (domNodeRef !== undefined || domNodeRef !== null) {
        if (!domNodeRef.current.contains(e.target)) {
          setSearch("");
        }
      }
    };
    document.addEventListener("mousedown", handler);

    return () => {
      document.addEventListener("mousedown", handler);
    };
  });

  return (
   <div className="header">
     <div className="header-content">
       <div className="searchh">
         <input 
           placeholder="Type to search"
           onChange={handleSearchChange}
         />
         {!!search && (
           <SearchDropDown 
             search={search}
             ref={domNodeRef}
           />
         )}
       </div>
     </div>
   </div>
  )

SearchDropDown 组件

const SearchDropDown = (props) => {
  ....
  return (
    <div className="search-drop-down" ref={props.ref}>
     .....
    </div>
  )
}

1 个答案:

答案 0 :(得分:2)

useRef 将返回一个一致对象。它永远不会是 nullundefined

将改变的是 ref 上的 .current 属性 - 这是您应该检查的内容,而不是 ref 对象本身。

if (domNodeRef !== undefined || domNodeRef !== null) {

应该改为

if (domNodeRef.current) {

还有

return () => {
  document.addEventListener("mousedown", handler);
};

应该

return () => {
  document.removeEventListener("mousedown", handler);
};

不过,您可能会考虑另一种方法 - 而不是 ref 和 .contains,只需检查目标是否具有搜索栏的 .closest 元素:

useEffect(() => {
    const handler = (e) => {
        if (!e.target.closest('.search-drop-down')) {
            setSearch("");
        }
    }
    document.addEventListener("mousedown", handler);
    return () => {
        document.removeEventListener("mousedown", handler);
    };
}, []);