reactjs - useEffect içinde useRef'e nasıl bir olay dinleyicisi eklenir


Bir ref'e bir olay dinleyicisi eklemek istediğim özel bir hook oluşturuyorum, ancak listRef ve listRef.current null olabileceği için temizlemeyi nasıl düzgün yapacağımı bilmiyorum:

export const myHook: MyHook = () => {
  const listRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    // I can check for the presence of `listRef.current` here ...
    if (listRef && listRef.current) {
      listRef.current.addEventListener(...)
    }

    // ... but what's the right way for the return function?
    return listRef.current.removeEventListener(...)
  })

  return [listRef]
}

Cevap #1

Düzenle :

Ama dönüş fonksiyonunda listRef varlığını da kontrol etmem gerekiyor, değil mi?

Evet, ve yapabileceğiniz şey her şeyi if cümlesinin etrafına sarmaktır

  useEffect(() => {
    // Everything around if statement
    if (listRef && listRef.current) {
      listRef.current.addEventListener(...)
    
      return () => {
        listRef.current.removeEventListener(...)
      }
    }
  }, [listRef])

Eğer addEventListener çağırmazsanız, removeEventListener çağırmanıza gerek yoktur, bu yüzden her şeyi if içine koyarsınız.


Temizlik işleminde yapmak istediğiniz şeyi yapacak bir fonksiyonu dönüşte geçirmeniz gerekiyor.

export const myHook: MyHook = () => {
  const listRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    // This is ok
    if (listRef && listRef.current) {
      listRef.current.addEventListener(...)
    }

    // Passing a function that calls your function
    return () => {
        listRef.current.removeEventListener(...)
    }
  }, [listRef])

  return [listRef]
}

Dikkat etmeniz gereken bir diğer şey, fooEventListener içinde, ...'in fonksiyonun aynı referansı olması gerektiğidir, bu şunu ifade eder:

Bunu yapmamalısın:

  useEffect(() => {
    if (listRef && listRef.current) {
      listRef.current.addEventListener(() => console.log('do something'))
    }

    return () => {
        listRef.current.removeEventListener(() => console.log('do something'))
    }
  })

Ve yapmalısın :

  useEffect(() => {
    const myFunction = () => console.log('do something')

    if (listRef && listRef.current) {
      // Passing the same reference
      listRef.current.addEventListener(myFunction)
    }

    return () => {
      // Passing the same reference
      listRef.current.removeEventListener(myFunction)
    }
  }, [listRef])

İlgili makaleler