How to avoid multiple event listeners from being attached?

Viewed 1101

Is the following code going to attach multiple event listeners or will React Native / expo-linking only allow one event listener be attached at a time?

import * as Linking from 'expo-linking'
import { useIsFocused } from '@react-navigation/native'

const MyComponent = () => {
  const isFocused = useIsFocused()

  useEffect(() => {
    fetchData()
    Linking.addEventListener('url', _handleEvent)
  }, [isFocused])

  const fetchData = () => {
    // ...
  }

  const _handleEvent = () => {
    // ...
  }

  return (
    <View><View>
  )
}

Is there are a way to check if an event listener already exists so I can do something like:

useEffect(() => {
  fetchData()
  if(!eventListenerExists){
    Linking.addEventListener('url', _handleEvent)
  }
}, [isFocused])
3 Answers

It'll attach multiple handlers, adding one each time isFocused changes. To remove the previous handler when attaching the next, return a function that React will call:

useEffect(() => {
  fetchData()
  Linking.addEventListener('url', _handleEvent)
  return () => Linking.removeEventListener('url', _handleEvent) // <======
}, [isFocused])

You want to do that anyway so that the handler is removed when your component is completely unmounted.

This is covered in the React documentation here.

I think even should call one time

useEffect(() => {
  Linking.addEventListener('url', _handleEvent)
  return () => Linking.removeEventListener('url', _handleEvent) // <======
}, [])

1、in the useEffect callback, return the function that remove the listener; 2、every time remove the listener before bind it. such as:

useEffect(() => {
    window.removeEventListener('url', hander);
    window.addEventListener('url', hander);
    return () => window.removeEventListener('url', hander);
}, [XXX])
Related