使用 HTMLAudioElement 时 useEffect 抛出 DOMException

useEffect throws DOMException when using HTMLAudioElement

我编写了一个名为 useAudio 的自定义 React 钩子来在我的应用程序后台播放声音。

为什么 useEffect 抛出 Uncaught (in promise) DOMException

我已将问题缩小到自定义挂钩中的第二个 useEffect。当指示音频是否为 playing 的布尔值发生变化时,此效果会运行。

React 所说的都是 Uncaught Error: The error you provided does not contain a stack trace.

我还尝试将 audio 修改为常规常量,而不是通过 useState 挂钩声明,但这并没有解决问题。

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

它在 live app 中工作。

不是在这个孤立的Codesandbox中工作。

我希望音频在安装组件时启动并且不会抛出 DOMExceptions。

关于您的应用程序,您有几个模糊的地方,包括在条件中使用挂钩和在状态中存储 audio 对象(尝试 useRef,这是它的唯一目的)。但是你喂给Audiourl问题的核心似乎是undefined。我想 CodeSandbox 环境没有适合 mp3 文件的加载程序。尝试直接 URL 代替。

沙盒:https://codesandbox.io/s/l7775jm2rm