Reputation: 114
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
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