Joe Previte
Joe Previte

Reputation: 114

useEffect throws DOMException when using HTMLAudioElement

I've written a custom React hook called useAudio to play sounds in the background of my app.

Why is useEffect throwing Uncaught (in promise) DOMException?

I've narrowed the issue down to the second useEffect inside my custom hook. This effect runs when a Boolean indicating whether the audio is playing changes.

All React says is Uncaught Error: The error you provided does not contain a stack trace.

I also tried modifying audio to be a regular constant instead of declaring via the useState hook but that didn't solve it.

import React, { useState, useEffect } from 'react'
import styled from 'styled-components'

const useAudio = (url: string) => {
  if (typeof Audio !== 'undefined') {
    const [audio] = useState(new Audio(url))
    const [playing, setPlaying] = useState(false)

    const toggle = () => setPlaying(!playing)

    useEffect(() => {
      audio.loop = true
      audio.autoplay = true
    })

    useEffect(() => {
      playing ? audio.play() : audio.pause()
      return () => {
        audio.pause()
      }
    }, [playing])

    return [playing, toggle]
  }
}

const AudioPlayer: React.FC<{ url: string }> = ({ url }) => {
  if (typeof Audio !== 'undefined') {
    const [playing, toggle] = useAudio(url)

    return (
      <AudioContainer>
        {typeof playing !== 'undefined' && (
          <Button onClick={() => toggle()}>
            {playing ? 'Stop music' : 'Play music'}
          </Button>
        )}
      </AudioContainer>
    )
  }
  return null
}

export default AudioPlayer

It's working in the live app.

it's not working in this isolated Codesandbox.

I expect the audio to start when the component is mounted and no DOMExceptions to be thrown.

Upvotes: 1

Views: 804

Answers (1)

jayarjo
jayarjo

Reputation: 16726

You've got several vague points about your app, including using hooks in conditional and storing audio object in state (try useRef instead, that's its only purpose). But the core of the problem it seems that url that you feed to Audio is undefined. I guess CodeSandbox environment doesn't have a proper loader for mp3 files. Try some direct URL instead.

Sandbox: https://codesandbox.io/s/l7775jm2rm

Upvotes: 1

Related Questions