React js中如何通过toggle按钮停止歌曲播放 点击暂停不生效怎么解决
问题根源
你把new Audio(music)直接写在了组件函数体内,React组件每次状态更新触发重渲染时,都会重新执行整个函数逻辑,生成全新的Audio实例。你点击切换到暂停状态时,操作的是本次渲染新生成的、根本没有在播放的Audio实例,之前正在播放的旧实例没有被调用pause方法,所以音乐不会停止。
修复方案
用useRef存储Audio实例,保证整个组件生命周期内只会初始化一次Audio对象,所有播放/暂停操作都指向同一个实例:
import { React, useState, useRef } from 'react'; import './audio.css'; import music from './BLOOD.mp3'; const PlaySong = () => { // 用useRef存储Audio实例,重渲染不会重置 const songRef = useRef(new Audio(music)); const [playMusic, setPlayMusic] = useState(false); const handlePlayMusic = () => { const currentSong = songRef.current; const newState = !playMusic; if(newState === true){ currentSong.play() } else { currentSong.pause(); } setPlayMusic(newState); } return ( <div className="container"> <div className="button r" id="button-4"> <input type="checkbox" className="checkbox" checked={playMusic} onChange={handlePlayMusic} /> <div className="knobs" /> <div className="layer" /> </div> </div> ) } export default PlaySong
额外优化点
- 给checkbox加上
checked={playMusic}属性,让组件状态和checkbox的选中状态完全同步,避免出现状态不一致的问题 - 若组件存在卸载场景,可添加useEffect清理逻辑,在组件卸载时暂停播放并释放音频资源,避免后台继续播放:
useEffect(() => { return () => { songRef.current.pause(); songRef.current = null; } }, [])
内容的提问来源于stack exchange,提问作者H. Sayouf
相关产品推荐
相关产品推荐

