Помните, что все в вашем теле функции будет выполняться при каждом рендере - поэтому в этом случае вы создаете новый soundObject
и потенциально запускаете вызов soundObject.loadAsync
для каждого отдельного рендера. Чтобы избежать этого, вам нужно воспользоваться другими хуками - в вашем случае вероятно useRef
и useEffect
. Я бы порекомендовал ознакомиться с ними через описание API-интерфейса hooks: https://reactjs.org/docs/hooks-reference.html
Вот краткий отчет о том, как избежать ненужных эффектов. Вы, вероятно, захотите просмотреть и настроить массивы зависимостей в зависимости от того, как вы хотите, чтобы вещи функционировали, и когда вы хотите, чтобы различные эффекты были перезапущены. Я не уверен, что вам когда-нибудь понадобится воссоздать, например, объект Sound
.
import React, { useState, useRef, useCallback, useEffect} from 'react';
import { Audio } from 'expo-av';
const AudioPlayer = ({ user }) => {
const [currentProgress, setCurrentProgress] = useState(0);
const soundObjectRef = useRef(new Audio.Sound());
useEffect(() => {
const playbackUpdate = (playbackObject) => {
setCurrentProgress(playbackObject.currentMillis);
// updating state with progress through audio file in milliseconds
}
soundObjectRef.current.setOnPlaybackStatusUpdate(playbackUpdate);
}, []); // do this only once per component mount
// sets a function that is called every 500 milliseconds as the audio is played
useEffect(() => {
if (user) {
soundObjectRef.current.loadAsync({user.message.path});
}
}, [user]); // run this anytime user changes but do not run again if user doesn't change
const play = () => {
soundObjectRef.current.playAsync();
}
return (
<View>
<Text>{currentProgress}</Text>
<Button title="play" onPress={play} />
</View>
)
}
export default AudioPlayer