reactjs - React 播放列表中改变歌曲,useEffect hook 依赖数组
问题描述
问题描述
我正在使用Soundcloud API制作播放列表播放器,但在单击下一首/上一首按钮以切换到下一首歌曲时遇到问题。使用钩子成功获取了初始歌曲,但是当在下一个/上一个按钮中执行方法useEffect
时,我不知道如何再次调用此钩子。onClick()
目前,播放/暂停按钮可以正常工作,但下一个/上一个按钮只能在涉及 { play/pause/previous/next } 按钮的某些特定点击序列下工作。考虑到我的 useEffect 钩子似乎是错误的,这是可以预料的。
JSFiddle(无法插入 Stackoverflow JS/HTML/CSS widjet)
[-------- 在这里工作 JSFiddle !!---------]
播放列表.tsx
import react, { useState, useEffect } from 'react';
const SC = require('soundcloud');
SC.initialize({
client_id: '1dff55bf515582dc759594dac5ba46e9'
});
const playlist = [
913128502,
755552476,
604329399
]
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';
const prevIcon = 'https://i.postimg.cc/xCry8pgt/prev2.png';
const nextIcon = 'https://i.postimg.cc/ncwmMwhB/next.png';
const musicFetch = (trackId) => {
return SC.stream('/tracks/' + trackId)
.then(track => {
return track;
})
}
const Playlist = () => {
const [playState, setPlayState] = useState(false);
const [track, setTrack] = useState<any>(null);
const [playlistIndex, setPlaylistIndex] = useState(0);
// use effect that fetches the initial song upong first render
useEffect(() => {
musicFetch(playlist[playlistIndex]).then((music) => {
music.setVolume(0.025); //increase if you don't hear background sound
setTrack(music);
});
}, [])
// use effect that should fetch new song upon clicking next or previous button
useEffect(() => {
musicFetch(playlist[playlistIndex]).then((music) => {
music.setVolume(0.2); //increase if you don't hear background sound
setTrack(music);
});
}, [setPlayState, playlistIndex])
const handleClick = async (direction) => {
direction === 'play' ? await enableMusic() : await changeMusic(direction);
}
const enableMusic = async () => {
if (track) {
setPlayState(!playState);
playState ? await track.pause() : await track.play();
}
}
const changeMusic = async (direction) => {
setPlaylistIndex(
direction === 'next' ? await playlistIndex+1 : await playlistIndex-1
);
}
return (
<div>
<img src={prevIcon}
onClick={() => { handleClick('prev') }}
height="100" width="100"/>
<img src={!playState ? playIcon : pauseIcon }
onClick={() => { handleClick('play') }}
height="100" width="100" >
</img>
<img src={nextIcon}
onClick={() => { handleClick('next') }}
height="100" width="100"/>
</div>
)
}
export default Playlist;
我尝试过的事情
我已阅读有关useEffect
钩子条件依赖数组的信息,并尝试在我的 useEffect 钩子中设置任何涉及setPlaylistindex
, playlistIndex
,的组合setTrack
,但没有成功。我已经考虑过这个useCallback
钩子,但这似乎不是正确的解决方案。
我试图找到一种卸载和挂载的方法,以便根据请求调用空依赖 useEffect 挂钩,我能够为此设计一个forceUpdate()
,但这也不能解决问题。
有谁知道我该如何解决这个问题?
解决方案
您需要useEffect
正确连接挂钩中的依赖项。
有单独useEffect
的钩子来捕捉播放/暂停和播放列表索引状态的变化。您可以将依赖项添加track
到useEffect
处理播放/暂停状态更改的挂钩并删除任何其他useEffect
挂钩,包括具有空依赖项列表的挂钩。
React.useEffect(async () => {
const music = await musicFetch(playlist[playlistIndex]);
music.setVolume(0.2);
setTrack(music);
}, [playlistIndex]);
React.useEffect(async ()=>{
playState ? await track.play() : await track.pause();
}, [track, playState]);
然后,您可以enableMusic
按如下方式重构方法
const enableMusic = async () => {
if (track) {
setPlayState(!playState);
}
}
推荐阅读
- apache-kafka - Azure eventthub as kafka:主题授权问题
- typescript - 运算符 '===' 不能应用于类型 '"x"' 和 'y'。三元运算符
- javascript - 正面和反面计数器
- node.js - 如何导出 TypeScript 模块以便可以从 TypeScript 和 Node 中导入?
- sql - 递归 SQL 查询以查找所有匹配的标识符
- curl - UrlFetch 相当于 CURL -u "
: " - ruby-on-rails - 在 Rails 5.2 中配置备份 gem - 执行 PostgreSQL 数据库的备份
- r - 通过列的完全匹配合并数据框
- java - 编写了一个语法并使用 ANTLR 创建了所有内容,试图弄清楚如何将其链接到 Java 程序
- angular - 在根 Angular 模块中导出