React SoundCloud播放列表播放器数据存储与播放暂停实现问题
核心问题
你当前的实现每次触发播放/暂停点击事件时,都会重新调用SC.stream拉取全新的曲目流实例,新实例的播放自然会从头开始,不符合你要续播/暂停的需求。你之前尝试的全局变量方案报错是因为异步请求尚未返回时就访问了未赋值的变量。
修正方案
使用React的useRef存储首次拉取到的曲目流实例,后续操作直接复用该实例,避免重复拉取:
const SC = require('soundcloud'); SC.initialize({ client_id: '1dff55bf515582dc759594dac5ba46e9' }); const playIcon = 'https://www.pngfind.com/pngs/m/20-201074_play-button-png-image-background-circle-transparent-png.png'; const pauseIcon = 'https://thumbs.dreamstime.com/z/pause-button-icon-transparent-background-sign-flat-style-204042531.jpg'; async function getJson(trackId) { let response = await SC.stream('/tracks/' + trackId); return response; } const Playlist = () => { const [playState, setPlayState] = React.useState(false); // 用ref存储拉取到的track实例,跨渲染周期保持不变,更新时不会触发组件重渲染 const trackRef = React.useRef<any>(null); const handlePlayClick = async () => { let currentTrack = trackRef.current; // 首次点击还没拉取过流,先拉取并存到ref里 if (!currentTrack) { currentTrack = await getJson(913128502); currentTrack.setVolume(0.025); trackRef.current = currentTrack; } // 直接操作已有的实例,不用重新拉取 playState ? currentTrack.pause() : currentTrack.play(); setPlayState(!playState); } return ( <img src={!playState ? playIcon : pauseIcon } onClick={handlePlayClick} height="100" width="100" alt="播放控制按钮" /> ) } export default Playlist;
补充说明
- 仅首次点击播放时会拉取流实例,后续播放/暂停操作均基于已有实例执行,不会触发歌曲重启
- 如果需要支持切换曲目,在切换逻辑中清空
trackRef.current并重置播放状态即可,新曲目首次点击时会自动拉取对应流实例 - 异步返回的实例只有在请求完成后才能访问,用
await等待异步逻辑执行完成再操作实例即可避免undefined报错
内容的提问来源于stack exchange,提问作者hexaquark
相关产品推荐
相关产品推荐

