0

Expo 文档指出Audio.Sound组件应该通过useEffect返回清理功能的 -hook 卸载。

const [sound] = useState(new Audio.Sound());
React.useEffect(() => {
return sound
  ? () => {
      console.log('Unloading Sound');
      sound.unloadAsync(); }
  : undefined;
}, [sound]);

我这样做但仍然收到警告

Warning: Can't perform a React state update on an unmounted component.

每次组件卸载时。

4

1 回答 1

0

问题是组件在调用清理函数和 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,..
}
于 2022-02-26T14:18:48.633 回答