#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
метод, который принимает aHTMLElement
в качестве входных данных, т.Е. Ссылка относится к aHTMLElement
.
Ответ №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>
, но это зависит от вашего варианта использования.