如何使用 Typescript 输入 ref 参数

Gij*_*rts 14 javascript typescript reactjs

我是 Typescript 的新手,目前正在尝试将我的 React.js 项目之一迁移到 Typescript。我偶然发现的事情之一是refs。我编写了一个使用 aref作为参数的钩子。基本上,它会检测 div 外部是否有单击,并触发作为第二个参数传递的函数。现在我想知道如何输入该特定的ref. 我尝试过不同的解决方案,例如React.RefObject<any>但不认为使用any是个好主意?我可以用什么来代替?值为undefined或 div(容器组件为样式组件),参见代码:

// How to type `ref`?
export function useOnClickOutside(ref: React.RefObject<any>, handler: Function) {
  useEffect(
    () => {
      const listener = (event: MouseEvent | TouchEvent) => {
        // Do nothing if clicking ref's element or descendent elements
        if (!ref.current || ref.current.contains(event.target)) {
          return
        }

        handler(event)
      }

      // MouseEvent
      document.addEventListener('mousedown', listener)
      // TouchEvent
      document.addEventListener('touchstart', listener)

      return () => {
        document.removeEventListener('mousedown', listener)
        document.removeEventListener('touchstart', listener)
      }
    },
    // Add ref and handler to effect dependencies
    [ref, handler]
  )
}


Run Code Online (Sandbox Code Playgroud)

成分

  const containerRef = React.useRef()
  useOnClickOutside(containerRef, () => setIsOpen(false))

  // Some code

  <Container ref={containerRef}>
    // Some code
  </Container
Run Code Online (Sandbox Code Playgroud)

所以基本上:应该<any>用什么来代替?提前致谢。

Tad*_*sen 9

与 ref 类型相关的唯一部分是这一行:

    if (!ref.current || ref.current.contains(event.target)) {
Run Code Online (Sandbox Code Playgroud)

这意味着 ref 具有一个将对象contains作为输入的方法EventTarget | null,因此要使其工作至少需要如下:

interface ValidRefTarget {
  contains(target: EventTarget | null): any;
}

export function useOnClickOutside(ref: React.RefObject<ValidRefTarget>, handler: (event: MouseEvent | TouchEvent)=>void ) {
Run Code Online (Sandbox Code Playgroud)

然而,由于此方法是由HTMLElement对象提供的,您可能只想使用它:

export function useOnClickOutside(ref: React.RefObject<HTMLElement>, handler: (event: MouseEvent | TouchEvent)=>void ) {
Run Code Online (Sandbox Code Playgroud)