UseEffect выдает исключение DOMException при использовании HTMLAudioElement

Я написал собственный хук 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 не будут выброшены.

Не следует использовать хуки в условных предложениях. Из документов/Правила хуков: Only call Hooks at the top level. Don’t call Hooks inside loops, conditions, or nested functions.

charlietfl 09.04.2019 04:11

Спасибо, что указали на это @charlietfl! Совсем забыл об этом. Так вы говорите, что проблема в том, что я звоню useEffect внутри этого условного if (typeof Audio !== 'undefined')?

Joe Previte 09.04.2019 04:15

Не уверен... но насколько я понимаю, может вызвать шаткое поведение

charlietfl 09.04.2019 04:16

Вы запрашиваете слишком много разрешений на этом своем сайте, вам действительно нужны все? Лично меня это заставило отказаться даже от попыток.

jayarjo 09.04.2019 07:50

Кстати, на портале StackExchange есть целый специальный сайт для просмотра кода: codereview.stackexchange.com. Такие вопросы лучше подходят там.

jayarjo 09.04.2019 08:17

Также не знал о codereview.stackexchange.com - в следующий раз опубликую там этот вопрос. Спасибо!

Joe Previte 10.04.2019 17:28
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
6
644
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У вас есть несколько неясных моментов в вашем приложении, в том числе использование хуков в условном выражении и сохранение объекта audio в состоянии (вместо этого попробуйте useRef, это его единственная цель). Но суть проблемы заключается в том, что url, которым вы кормите Audio, является undefined. Я предполагаю, что в среде CodeSandbox нет подходящего загрузчика для mp3 файлов. Вместо этого попробуйте какой-нибудь прямой URL.

Песочница: https://codesandbox.io/s/l7775jm2rm

Итак, чтобы решить эту проблему, я попробую: - не использовать хуки в условном выражении - хранить audio с useRef И вы заработали в CodeSandbox. Большое спасибо @jayarjo!

Joe Previte 10.04.2019 17:26

Другие вопросы по теме