如何使用 componentWillUnmount()?

如何解决如何使用 componentWillUnmount()?

我是使用 React-Native 的新手,我正在为流媒体应用程序创建音乐播放器,几乎一切正常,它在后台播放,但是当我想切换到另一个专辑或播放列表时,它不会剪切歌曲即播放新曲,同时播放上一曲和新曲。

它向我显示了这个警告:

警告:无法对卸载的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要解决此问题,请取消 componentwillUnmount 方法中的所有订阅和异步任务。

但是我不知道如何取消所有订阅和异步任务。

这是我的代码

import {
  StyleSheet,TouchableOpacity,View,Image,imagebackground,Slider,} from "react-native";
import { Title,Text } from "react-native-paper";
import { LinearGradient } from "expo-linear-gradient";
import { Button } from "../components/Button";
import { Audio,Video } from "expo-av";
import firebase from "../utils/firebase";
import "firebase/firestore";
import { Ionicons } from "@expo/vector-icons";

export default function ReproductorAudio(props) {
  const { route } = props;
  const { canciones } = route.params;
  const [duration,setDuration] = useState(0);
  const [totalDuration,setTotalDuration] = useState(0);

  const cancionesPlaylist = canciones;

  console.log(cancionesPlaylist);

  return (
    <ReproductorMusica
      duration={duration}
      cancionesPlaylist={cancionesPlaylist}
      totalDuration={totalDuration}
    />
  );
}

class ReproductorMusica extends React.Component {
  state = {
    isPlaying: false,playbackInstance: null,currentIndex: 0,duration: 0,volume: 1.0,isBuffering: false,isMounted: false,totalDuration: 0,};

  async componentDidMount() {
    this.isMounted = true;

    try {
      await Audio.setAudioModeAsync({
        allowsRecordingIOS: false,interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,playsInSilentModeIOS: true,interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DUCK_OTHERS,shouldDuckAndroid: true,staysActiveInBackground: true,playThroughEarpieceAndroid: true,});

      this.loadAudio();
    } catch (e) {
      console.log(e);
    }
  }

  async componentwillUnmount() {
    Audio.setAudioModeAsync({
      allowsRecordingIOS: false,});
  }

  async loadAudio() {
    const { currentIndex,isPlaying,volume } = this.state;

    try {
      const playbackInstance = new Audio.sound();
      const source = {
        uri: this.props.cancionesPlaylist[currentIndex].song,};

      const status = {
        shouldplay: isPlaying,volume,};

      playbackInstance.setonPlaybackStatusUpdate(this.onPlaybackStatusUpdate);
      await playbackInstance.loadAsync(source,status,false);
      this.setState({ playbackInstance });
    } catch (e) {
      console.log(e);
    }
  }

  onPlaybackStatusUpdate = (status) => {
    this.setState({
      isBuffering: status.isBuffering,});
  };

  handlePlayPause = async () => {
    const { isPlaying,playbackInstance } = this.state;
    isPlaying
      ? await playbackInstance.pauseAsync()
      : await playbackInstance.playAsync();

    this.setState({
      isPlaying: !isPlaying,});
  };

  handlePrevIoUsTrack = async () => {
    let { playbackInstance,currentIndex } = this.state;
    if (playbackInstance) {
      await playbackInstance.unloadAsync();
      currentIndex < this.props.cancionesPlaylist.length - 1
        ? (currentIndex -= 1)
        : (currentIndex = 0);
      this.setState({
        currentIndex,});
      this.loadAudio();
    }
  };

  handleNextTrack = async () => {
    let { playbackInstance,currentIndex } = this.state;
    if (playbackInstance) {
      await playbackInstance.unloadAsync();
      currentIndex < this.props.cancionesPlaylist.length - 1
        ? (currentIndex += 1)
        : (currentIndex = 0);
      this.setState({
        currentIndex,});
      this.loadAudio();
    }
  };

  renderFileInfo() {
    const {
      playbackInstance,currentIndex,duration,totalDuration,} = this.state;

    return playbackInstance ? (
      <View style={styles.trackInfo}>
        <Image
          style={styles.albumCover}
          source={{
            uri: this.props.cancionesPlaylist[currentIndex].image,}}
        />
        <Title style={[styles.trackInfoText,styles.largeText]}>
          {this.props.cancionesPlaylist[currentIndex].name}
        </Title>
        <Title style={[styles.trackInfoText,styles.smallText]}></Title>
        <View style={styles.progressContainer}>
          <Slider
            totalDuration={this.props.cancionesPlaylist[currentIndex].duracion}
            onValueChange={(value) =>
              this.props.cancionesPlaylist[duration](value)
            }
          />
          <View style={styles.durationContainer}>
            <Text style={styles.durationTextLeft}>{duration}</Text>
            <Text style={styles.durationTextRight}>
              -{(totalDuration - duration).toFixed(2)}
            </Text>
          </View>
        </View>
        {/*<Title style={[styles.trackInfoText,styles.smallText]}>
          {this.props.cancionesPlaylist[currentIndex].pista}
        </Title>*/}
      </View>
    ) : null;
  }

  render() {
    const { playbackInstance,currentIndex } = this.state;

    return (
      <imagebackground
        style={styles.backgroundImage}
        source={{
          uri: this.props.cancionesPlaylist[currentIndex].image,}}
        blurRadius={25}
      >
        <View style={styles.container}>
          {this.renderFileInfo()}
          <View style={styles.controls}>
            <TouchableOpacity
              style={styles.control}
              onPress={this.handlePrevIoUsTrack}
            >
              <Ionicons
                name="arrow-back-circle-outline"
                size={48}
                color="#fff"
              />
            </TouchableOpacity>
            <TouchableOpacity
              style={styles.control}
              onPress={this.handlePlayPause}
            >
              {this.state.isPlaying ? (
                <Ionicons name="ios-pause" size={48} color="#fff" />
              ) : (
                <Ionicons name="ios-play-circle" size={48} color="#fff" />
              )}
            </TouchableOpacity>
            <TouchableOpacity
              style={styles.control}
              onPress={this.handleNextTrack}
            >
              <Ionicons
                name="arrow-forward-circle-outline"
                size={48}
                color="#fff"
              />
            </TouchableOpacity>
          </View>
        </View>
      </imagebackground>
    );
  }
}

const styles = StyleSheet.create({
  backgroundImage: {
    position: "absolute",top: 0,left: 0,bottom: 0,right: 0,},container: {
    flex: 1,backgroundColor: "rgba(189,0.3)",alignItems: "center",justifyContent: "center",albumCover: {
    width: 250,height: 250,borderRadius: 10,borderWidth: 5,borderColor: "#fff",trackInfo: {
    padding: 40,paddingBottom: 0,//backgroundColor: "#000",trackInfoText: {
    textAlign: "center",flexWrap: "wrap",color: "#fff",largeText: {
    fontSize: 22,smallText: {
    fontSize: 16,control: {
    margin: 20,controls: {
    flexDirection: "row",durationContainer: {
    flexDirection: "row",durationTextLeft: {
    flex: 0.5,textAlign: "left",fontSize: 16,fontWeight: "bold",color: "white",durationTextRight: {
    flex: 0.5,textAlign: "right",});  ```

解决方法

这似乎是一个架构问题。

如果您在 ReproductorMusica 中并且需要离开该屏幕转到 AlbumScreen,则您不会卸载最后一个实例(您已经丢失了,因为您在ReproductorMusica)。

要解决此问题,您的 Audio.Sound 需要“全局且唯一”。因此,您可以从任何屏幕访问,而且始终是同一个实例。

,

我真的鼓励您将组件更改为功能组件。您无缘无故地同时使用这两种组件,并且类组件更难使用状态管理。您可以更改为功能组件并仅使用“useEffect”钩子来完成您需要的一切。在此处阅读更多信息:https://reactjs.org/docs/hooks-effect.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?