问题是组件在调用清理函数和 unloadAsync() 异步返回之间Audio.Sound
向注册的回调发送了回放状态更新。sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate)
并且该回调更新了已卸载的其他状态组件。
解决方案
向组件添加一个布尔变量(不是 useState 变量,因为它不会立即更新),该变量在 cleanup 函数中设置,并充当播放状态回调的保护。
const [audio] = useState(new Audio.Sound());
let isUnmounting = false;
useEffect(() => {
loadAudio(url).then(() => consoloe.log("loaded audio"));
return () => {
isUnmounting = true;
audio.unloadAsync().then(() => console.log("unloaded audio"));
};
}, [audio]);
async function loadAudio(url) {
// ...
audio.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
try {
await audio.loadAsync(url);
// ...
} catch {
console.log("Error loading audio");
}
}
const onPlaybackStatusUpdate = (status) => {
// this protects against updates on unmounted components
// when callback is fired while component is dismounting
if (isUnmounting) return;
// ... set the state components you need, like durationInMillis,..
}