H.sha
H.sha

Reputation: 61

React.js - removeEvent() in useEffect() hook

I'm trying to get the HTML5 audio element to autoplay on page load. I know that Chrome doesn't allow autoplay by default, unless something triggers it. So I've created a couple of event listeners within the useEffect() hook:

const Audio = () => {
  const audioPlayer = document.getElementById('myAudio')
  const playAudio = () => audioPlayer.play()
  useEffect(() => {
    window.addEventListener('scroll', playAudio)
    window.addEventListener('mousemove', playAudio)
    return () => {
      window.removeEventListener('scroll', playAudio)
      window.removeEventListener('mousemove', playAudio)
    }
  }, [])
  return (
    <audio
      id="myAudio"
      src={ audioAssetHere }
    />
  )
}

This does work but it keeps playing every time the cursor moves. I only want it to play once. I also get this error in the console:

DOMException: play() failed because the user didn't interact with the document first

And yet the audio still works every time the cursor moves.

I also tried using useRef and assign it to the audio tag ref={audioRef}, and then used it within the useEffect hook:

const audioRef = useRef()
const playAudio = () => audioRef.current.play()
useEffect(() => {
    window.addEventListener('scroll', playAudio)
    window.addEventListener('mousemove', playAudio)
    return () => {
      window.removeEventListener('scroll', playAudio)
      window.removeEventListener('mousemove', playAudio)
    }
  }, [])

This gives the error:

TypeError: audioRef.current.play is not a function

So in a nutshell, what I want is the audio to play every time the page loads. And I only want it to play once.

Any help would be greatly appreciated. Thanks

Upvotes: 1

Views: 125

Answers (1)

Evgeny Zaytsev
Evgeny Zaytsev

Reputation: 198

you are trying to play audio on every mousemove/scroll event, instead of it you just need to play it once on the first mousemove/scroll event:

const Audio = () => {
  const audioRef = React.useRef();

  useEffect(() => {
    const playAudio = () => {
      audioRef.current.play();
      removeListeners()
    }

    window.addEventListener('scroll', playAudio)
    window.addEventListener('mousemove', playAudio)
    
    const removeListeners = () => {
      window.removeEventListener('scroll', playAudio)
      window.removeEventListener('mousemove', playAudio)
    }
    
    return () => {
      removeListeners()
    }
  }, [])
  
  return (
    <audio
      src={ audioAssetHere }
      ref={ audioRef }
    />
  )
}

Upvotes: 2

Related Questions