Я написал собственный хук React под названием useAudio
для воспроизведения звуков в фоновом режиме моего приложения.
Почему 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
Работает в живое приложение.
это нет работает в этом изолированном Кодыпесочница.
Я ожидаю, что звук начнется, когда компонент будет смонтирован, и исключения DOMException не будут выброшены.
Спасибо, что указали на это @charlietfl! Совсем забыл об этом. Так вы говорите, что проблема в том, что я звоню useEffect
внутри этого условного if (typeof Audio !== 'undefined')
?
Не уверен... но насколько я понимаю, может вызвать шаткое поведение
Вы запрашиваете слишком много разрешений на этом своем сайте, вам действительно нужны все? Лично меня это заставило отказаться даже от попыток.
Кстати, на портале StackExchange есть целый специальный сайт для просмотра кода: codereview.stackexchange.com. Такие вопросы лучше подходят там.
Также не знал о codereview.stackexchange.com - в следующий раз опубликую там этот вопрос. Спасибо!
У вас есть несколько неясных моментов в вашем приложении, в том числе использование хуков в условном выражении и сохранение объекта audio
в состоянии (вместо этого попробуйте useRef
, это его единственная цель). Но суть проблемы заключается в том, что url
, которым вы кормите Audio
, является undefined
. Я предполагаю, что в среде CodeSandbox нет подходящего загрузчика для mp3
файлов. Вместо этого попробуйте какой-нибудь прямой URL.
Песочница: https://codesandbox.io/s/l7775jm2rm
Итак, чтобы решить эту проблему, я попробую: - не использовать хуки в условном выражении - хранить audio
с useRef
И вы заработали в CodeSandbox. Большое спасибо @jayarjo!
Не следует использовать хуки в условных предложениях. Из документов/Правила хуков:
Only call Hooks at the top level. Don’t call Hooks inside loops, conditions, or nested functions.