Как ввести параметр ref с помощью Typescript

#javascript #reactjs #typescript

#javascript #reactjs #typescript

Вопрос:

Я новичок в Typescript, и в настоящее время я пытаюсь перенести один из своих React.js проекты на машинописном языке. Одна из вещей, на которые я натыкаюсь refs . Я написал хук, который использует a ref в качестве параметра paremeter . В основном он определяет, есть ли щелчок за пределами 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]
  )
}


  

Компонент

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

  // Some code

  <Container ref={containerRef}>
    // Some code
  </Container
  

Итак, в основном: что должно <any> быть вместо этого? Заранее спасибо.

Комментарии:

1. Вы можете использовать <HTMLDivElement> , как указано в medium.com/@martin_hotell /…

2. Это необязательно или вы всегда будете получать?

3. ref.current.contains(event.target) это означает, что ваша ссылка должна быть введена, чтобы иметь contains метод, который принимает a HTMLElement в качестве входных данных, т.Е. Ссылка относится к a HTMLElement .

Ответ №1:

единственная часть, которая связана с типом ссылки, — это эта строка:

     if (!ref.current || ref.current.contains(event.target)) {
  

Это означает, что ref — это то, что имеет contains метод, который принимает в качестве входных EventTarget | null данных объект, поэтому минимум, который вам понадобится, чтобы заставить его работать, это:

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

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

Однако, поскольку этот метод предоставляется HTMLElement объектом, вы, вероятно, захотите просто использовать его вместо этого:

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

Комментарии:

1. RefObject<HTMLElement> отлично работает при вводе реквизита, спасибо.

2. Работает ли это для ссылок, определенных как функции?

3. @k3liutZu не уверен, что я понимаю, что вы имеете в виду, но в целом вы передаете тип данных, на которые, как вы ожидаете, будет сохранена ссылка, в generic of RefObject , так что это может выглядеть примерно так RefObject<(a:string) => void> , но это зависит от вашего варианта использования.