gpt4 book ai didi

javascript - 从流音频函数更新 useState 时无限重新渲染

转载 作者:行者123 更新时间:2023-12-01 00:35:25 25 4
gpt4 key购买 nike

我正在构建一个应用程序 React Native,其中我将一组音频文件发送到 Expo AV Audio.Sound 对象中,加载它们,播放它们,然后尝试使用以下信息更新应用程序本身的显示正在播放的音频文件(具体是用户播放文件的距离)。我正在尝试通过 useState Hook 更新显示,该 Hook 由音频播放器的回调函数调用。

我遇到的问题是,每当我尝试更改音频播放器回调函数的状态时,我就会陷入无限的重新渲染。简化代码如下:

import React, { useState} from 'react';
import { Audio } from 'expo-av';

const AudioPlayer = ({ user }) => {
const [currentProgress, setCurrentProgress] = useState(0);

const soundObject = new Audio.Sound();
soundObject.setOnPlaybackStatusUpdate(playbackUpdate);
// sets a function that is called every 500 milliseconds as the audio is played

if(user) {
soundObject.loadAsync({user.message.path});
}

const play = () => {
soundObject.playAsync();
}

const playbackUpdate = (playbackObject) => {
setCurrentProgress(playbackObject.currentMillis);
// updating state with progress through audio file in milliseconds
}

return (
<View>
<Text>{currentProgress}</Text>
<Button title="play" onPress={play} />
</View>
)

}

export default AudioPlayer

最佳答案

请记住,函数体内的所有内容都将在每次渲染上运行 - 因此在本例中,您将创建一个新的 soundObject 并可能在每个渲染上运行 soundObject.loadAsync 调用单一渲染。您需要利用其他 Hook 来避免这种情况 - 在您的情况下可能是 useRefuseEffect。我建议通过 hooks api 引用来熟悉这些:https://reactjs.org/docs/hooks-reference.html

以下是我如何避免不必要的影响的快速说明。您可能需要根据您希望事物如何运行以及何时重新运行各种效果来检查和调整依赖项数组。例如,我不确定您是否需要重新创建 Sound 对象。

import React, { useState, useRef, useCallback, useEffect} from 'react';
import { Audio } from 'expo-av';
import { Button, View, Text } from 'react-native';

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

关于javascript - 从流音频函数更新 useState 时无限重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58170825/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com