【问题标题】:useState() causes unexpected behaviour with audio objectuseState() 导致音频对象出现意外行为
【发布时间】:2020-11-19 20:28:38
【问题描述】:

我正在尝试创建一个基本的音频播放器并使用状态挂钩跟踪播放器状态。

以下代码创建具有以下行为的组件:

  1. 第一次按下按钮时播放音频
  2. 每次按下按钮时,文本都会正确切换
  3. 当播放状态时,调用 player.pause() 什么都不做
  4. 当状态未播放时,音频会继续播放,调用 player.play() 会导致第二层音频从顶部开始
    import React, {useState} from 'react'
    
    function InlinePlayer ({audio}) {
      const [playing, setPlaying] = useState(false)
    
      const player = new Audio(audio.asset.url)
    
      function togglePlay () {
        playing ? player.pause() : player.play()
        setPlaying(!playing)
      }
    
      return <>
        <button onClick={() => togglePlay()}>
          {playing ? 'Stop' : 'Play' }
        </button>
      </>
    }
    
    export default InlinePlayer

如果我根本不使用状态挂钩,我可以毫无问题地停止和启动音频。

一个奇怪的事情是,即使我无条件地调用 play() 然后调用状态钩子,随后对 pause() 的调用也不再起作用。就好像调用 setPlaying() 会破坏与播放器对象的连接。如果我注释掉 setPlaying 行,它可以工作。

  function play () {
    player.play()
    setPlaying(true)
  }

  function pause () {
    player.pause()
    setPlaying(false)
  }

我最初认为问题在于状态是异步设置的,因此条件播放是罪魁祸首。这里似乎有什么?

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    player.pause()player.play() 就像副作用一样。使用具有适当清理功能的useEffect,以便您可以切换play/pause

    import React, { useState, useEffect } from "react";
    
    function InlinePlayer({ audio }) {
      const [playing, setPlaying] = useState(false);
    
      const player = new Audio(
        "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
      );
    
      useEffect(() => {
        playing ? player.play() : player.pause();
    
        // This is cleanup of the effect
        return () => player.pause();
    
      }, [playing]);
       // ^ Run the effect every time the `playing` is changed
    
      function togglePlay() {
        // Using the callback version of `setState` so you always
        // toggle based on the latest state
        setPlaying(s => !s);
      }
    
      return (
        <>
          <button onClick={() => togglePlay()}>{playing ? "Stop" : "Play"}</button>
        </>
      );
    }
    

    【讨论】:

    • 太好了,我有一种感觉,我必须使用 useEffect,但不知道如何使用。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    • 2021-07-01
    • 2021-07-29
    相关资源
    最近更新 更多