首页 > 解决方案 > ReactNative & Expo - 错误:“值”是只读的

问题描述

我正在向这个反应原生应用程序添加一个音乐播放器组件/功能。我将包含所有相关代码,以便您更好地了解设置。

在处理音乐播放器逻辑的上下文文件 MusicContext.js 中,我有几个 State 对象用于确定播放哪首歌。

const initialState = {
  startMusic: () => null,
  stopMusic: () => null,
  soundObject: null,
  isPlaying: false,
  currentIndex: 0
}

我的歌曲数组:

mainTheme = new Audio.Sound()
mainTheme2 = new Audio.Sound()
mainTheme3 = new Audio.Sound()

const songs = [
  { path: require("../assets/sounds/MainTheme.mp3"), song: mainTheme },
  { path: require("../assets/sounds/MainTheme2.mp3"), song: mainTheme2 },
  { path: require("../assets/sounds/MainTheme3.mp3"), song: mainTheme3 },
]

currentIndex 从 0 开始,因此音乐播放器将从歌曲 [0] 开始。

开始播放音乐的函数如下:

const startMusic = async () => {
    try {
      const songToPlay = songs[currentIndex].song  // first song in the array of songs
      const source = songs[currentIndex].path      // the path that loadAsync() function needs to load file

      await songToPlay.loadAsync(source)
      await songToPlay.playAsync()
      setSoundObject(songToPlay)
      setIsPlaying(true)
      return new Promise(resolve => {
        songToPlay.setOnPlaybackStatusUpdate(playbackStatus => {
          if (playbackStatus.didJustFinish) {
            console.log("Song finished")
            resolve()
          }
        })
      })
    } catch (error) {
      console.log(`Error: ${error}`)
      return
    }
  }

此时,soundObject = 正在播放的歌曲,currentIndex = 0。我跳到下一首歌的函数是:

const handleNextTrack = async () => {
    if (soundObject) {
      await soundObject.stopAsync()
      await soundObject.unloadAsync()
      setSoundObject(null)

      currentIndex < songs.length - 1 ? (currentIndex += 1) : (currentIndex = 0)

      setCurrentIndex({ currentIndex })

      this.startMusic()
    }
  }

之后,它回到startMusic(),除了现在 currentIndex 为 1,它应该播放数组中的下一首歌曲。

我得到的错误是 Possible Unhandled Promise Rejection (id: 5): Error: "currentIndex" is read-only

我尝试了几种不同的实现方式,handleNextTrack但都导致了同样的错误。

更新

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()
    }
  }

  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() 
    } 
  }

歌曲[0] 在应用打开时播放。<~好

next 当我点击<~BAD时,歌曲 [0] 再次播放

Song[1] 只有在我next第二次击球时才会播放 <~GOOD

如果我再次击球,就会播放歌曲 [2] next<~GOOD

之后,我可以循环一点,击打previous几次next,但它刚刚坏了,并且声音对象不知何故又回到了null

标签: androidreactjsreact-nativeexpomobile-development

解决方案


推荐阅读