.play() 在 React 组件上无法按预期工作

Posted

技术标签:

【中文标题】.play() 在 React 组件上无法按预期工作【英文标题】:.play() does not works as expected on a React Component 【发布时间】:2021-05-12 15:00:15 【问题描述】:

我正在构建一个音频播放器,但是当我尝试播放音频标签时,它无法按预期工作。我正在使用useEfect()useRef() 调用.play().pause() 来播放.mp3,但此方法总是返回一个始终为pending 状态的Promise,并且不执行.then() 或@987654327 @。有谁知道如何解决这个问题?

我的组件代码:

import React,  useState, useEffect, useRef  from 'react';
import Details from '../Details';
import Controls from '../Controls';

function Player(props) 
  const audioEl = useRef(null);

  const [isPlaying, setIsPlaying] = useState(false);

  useEffect(() => 
    if (isPlaying) 
      let promisseTemp = audioEl.current.play();
      if (promisseTemp !== undefined)
        promisseTemp
          .then((_) => 
            console.log('OK');
          )
          .catch((erro) => console.log(erro));
     else 
      let promisseTemp = audioEl.current.pause();
      if (promisseTemp !== undefined)
        promisseTemp
          .then((_) => 
            console.log('OK');
          )
          .catch((erro) => console.log(erro));
    
  );

  const skipEpisode = (forwards = true) => 
    if (forwards) 
      props.setCurrentEpisodeIndex(() => 
        let temp = props.currentEpisodeIndex;
        temp++;

        if (temp > props.episodes.length - 1) return 0;
        return temp;
      );
     else 
      props.setCurrentEpisodeIndex(() => 
        let temp = props.currentEpisodeIndex;
        temp--;

        if (temp < 0) return props.episodes.length - 1;
        return temp;
      );
    
  ;

  return (
    <div className="Player">
      <audio scr=window.location.origin + props.episodes[props.currentEpisodeIndex].scr ref=audioEl></audio>
      <h4>Playing now</h4>
      <Details episode=props.episodes[props.currentEpisodeIndex] />
      <Controls isPlaying=isPlaying setIsPlaying=setIsPlaying skipEpisode=skipEpisode />
    </div>
  );


export default Player;

【问题讨论】:

【参考方案1】:

您的useEffect 应该如下所示:

useEffect(() => 
    if (audioEl.current) 
        if (isPlaying) 
            audioEl.current.play()
                .then((_) => 
                    console.log("OK");
                )
                .catch((erro) => console.log(erro));
         else 
            audioEl.current.pause()
                .then((_) => 
                    console.log("OK");
                )
                .catch((erro) => console.log(erro));
        
    
, [isPlaying]);

您缺少useEffect 中的第二个参数,在当前状态下,每次渲染都会调用它。您想添加依赖项数组作为第二个参数。在您的情况下,[isPlaying] 每次 isPlaying 更改时都会调用它。

您可能应该确保在对其调用方法之前也定义了audioEl.current

【讨论】:

以上是关于.play() 在 React 组件上无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

React-Native Geolocation 在 Android 上无法按预期工作

路由器事件在构造函数上使用时会导致错误警告:无法对未安装的组件执行 React 状态更新

React onChange没有按预期工作

当父组件已经定义了样式时,CSS 未按预期在 React Native 中应用

Javascript 地图方法无法按预期工作

我可以将 React 应用程序用作静态 HTML 页面上的组件吗