ReactNative & Expo:在数组中循环递增/递减时遇到麻烦



我正在尝试循环浏览数组中的声音对象,使用从 0 开始的索引值,并根据我按下一步还是向后递增/递减。

这适用于使用 Expo//expo-av 库的 react-native 音乐播放器。我将包括所有相关代码。

我在上下文文件中的状态:

const initialState = {
startMusic: () => null,
stopMusic: () => null,
soundObject: null,
isPlaying: false,
currentIndex: 0,
}
useState()
const [soundObject, setSoundObject] = useState(initialState.soundObject)
const [isPlaying, setIsPlaying] = useState(initialState.isPlaying)
const [currentIndex, setCurrentIndex] = useState(initialState.currentIndex)

启动音乐功能

const startMusic = async () => {
try {
const songToPlay = songs[currentIndex].song
const source = songs[currentIndex].path
await songToPlay.loadAsync(source)
await songToPlay.playAsync()
setSoundObject(songToPlay)
setIsPlaying(true)
return new Promise(resolve => {      // I made this promise when I was setting a loop to play through music.  May not need this anymore
songToPlay.setOnPlaybackStatusUpdate(playbackStatus => {
if (playbackStatus.didJustFinish) {
console.log("Song finished")
resolve()
}
})
})
} catch (error) {
console.log(`Error: ${error}`)
return
}
}

最后,应该循环播放歌曲的处理程序函数:

const handlePreviousTrack = async () => {
if (soundObject) {
await soundObject.stopAsync()
await soundObject.unloadAsync()
// setSoundObject(null)
let newIndex = currentIndex
newIndex < songs.length - 1 ? newIndex-- : (newIndex = 0)
setCurrentIndex(newIndex)
startMusic()
console.log(currentIndex)
}
}
const handleNextTrack = async () => {
if (soundObject) {
await soundObject.stopAsync()
await soundObject.unloadAsync()
// setSoundObject(null)
let newIndex = currentIndex
newIndex < songs.length - 1 ? newIndex++ : (newIndex = 0)
setCurrentIndex(newIndex)
startMusic()
console.log(currentIndex)
}
}

循环浏览下一个/上一个不按顺序进行。 有时它有效,有时上一首转到下一首歌曲,有时按下一首只是重播第一首歌曲。

我是否错误地通过当前索引操纵状态?

通过快速浏览,我没有看到上面的代码中有任何惊人的错误。 我的一个建议是将startMusic()调用从两个handleTrack方法中删除,而是让它们像现在一样设置索引状态。

而是添加一个每次索引更改时都会触发的useEffect,并将startMusic()置于该 useEffect 中。

它看起来像这样:

useEffect(() => {
... (other logic)
startMusic()
}, [currentIndex])

这将确保startMusic只会在当前索引状态更改后被调用,并且不会太快被调用等。 如果不是,则无论状态何时更改,都可以更轻松地跟踪

最新更新