Reactjs useState()导致音频对象出现意外行为

Reactjs useState()导致音频对象出现意外行为,reactjs,react-hooks,Reactjs,React Hooks,我正在尝试创建一个基本的音频播放器,并使用状态挂钩跟踪播放器的状态 以下代码创建具有以下行为的组件: 首次按下按钮时,音频播放 每次按下按钮时,文本都会正确切换 当状态为播放时,调用player.pause()不会执行任何操作 当状态为“不播放”时,音频将继续,并调用player.play()使第二层音频从顶部开始 我最初认为问题在于状态是异步设置的,因此条件播放是罪魁祸首。这里好像有什么?player.pause()和player.play()都有副作用。使用带有适当清理功能的useffect

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

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

  • 首次按下按钮时,音频播放
  • 每次按下按钮时,文本都会正确切换
  • 当状态为播放时,调用player.pause()不会执行任何操作
  • 当状态为“不播放”时,音频将继续,并调用player.play()使第二层音频从顶部开始
  • 我最初认为问题在于状态是异步设置的,因此条件播放是罪魁祸首。这里好像有什么?player.pause()和player.play()都有副作用。使用带有适当清理功能的
    useffect
    ,以便可以切换
    播放/暂停

    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>
        </>
      );
    }
    
    import React,{useState,useffect}来自“React”;
    函数InlinePlayer({audio}){
    const[playing,setPlaying]=useState(false);
    const player=新音频(
    "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
    );
    useffect(()=>{
    播放?播放。播放():播放。暂停();
    //这是效果的清理
    return()=>player.pause();
    },[玩];
    //^每次更改“播放”时运行效果
    函数togglePlay(){
    //使用“setState”的回调版本,因此
    //基于最新状态进行切换
    设置播放(s=>!s);
    }
    返回(
    togglePlay()}>{播放?“停止”:“播放”}
    );
    }
    
    player.pause()
    player.play()
    类似于副作用。使用带有适当清理功能的
    useffect
    ,以便可以切换
    播放/暂停

    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>
        </>
      );
    }
    
    import React,{useState,useffect}来自“React”;
    函数InlinePlayer({audio}){
    const[playing,setPlaying]=useState(false);
    const player=新音频(
    "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
    );
    useffect(()=>{
    播放?播放。播放():播放。暂停();
    //这是效果的清理
    return()=>player.pause();
    },[玩];
    //^每次更改“播放”时运行效果
    函数togglePlay(){
    //使用“setState”的回调版本,因此
    //基于最新状态进行切换
    设置播放(s=>!s);
    }
    返回(
    togglePlay()}>{播放?“停止”:“播放”}
    );
    }
    
    太好了,我觉得我必须使用useEffect,但不知道如何使用。谢谢太好了,我有一种感觉,我必须使用useEffect,但不知道如何使用。谢谢
    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>
        </>
      );
    }