带有异步功能的useEffect播放声音不起作用

时间:2019-12-26 17:41:57

标签: reactjs react-native expo

我试图在HomeScreen加载后立即在React Native / Expo应用程序中播放背景音乐。

使用expo AV库,我使用一种启动音乐的方法设置了MusicContext。这是我的MusicContext.js

import React, {
  useState,
  useCallback,
  useMemo,
  useContext,
  useEffect,
} from "react"
import PropTypes from "prop-types"
import { Audio } from "expo-av"

const initialState = {
  playMusic: false,
  setPlayMusic: () => null,
}

export const MusicContext = React.createContext(initialState)

const startMusic = async () => {
  let mainTheme = null

  if (!mainTheme) {
    mainTheme = new Audio.Sound() 
  try {
    console.log("trying")
    await mainTheme.loadAsync(require("../assets/sounds/MainTheme.mp3"))
    mainTheme.setStatusAsync({ isLooping: true })
  } catch (error) {
    console.log("Couldnt load main theme")
    return
  }
}
}

export const MusicProvider = props => {
  const [playMusic, setPlayMusic] = useState(initialState.playMusic)

  return (
    <MusicContext.Provider
      value={{
        playMusic,
        setPlayMusic,
        startMusic,
      }}
    >
      {props.children}
    </MusicContext.Provider>
  )
}

MusicContext.propTypes = {
  children: PropTypes.node.isRequired,
}

然后我在主屏幕上的startMusic中调用useEffect方法。

const HomeScreen = () => {
  const { startMusic } = useContext(MusicContext)

  useEffect(() => {
    console.log("running")
    startMusic()
  }, []) 

我看到了所有console.log输出,因此我知道它正在运行,但是音乐永远不会播放。我在这里想念什么?

1 个答案:

答案 0 :(得分:0)

您是否没有将startMusic放在initialState中的原因?

将函数放在initalState中时,它会被正确调用。

要更广泛地回答您的问题,您需要将aysnc函数包装在IIFE中,或者将其作为单独的被调用函数。

我通常将其包装为IIFE。