No se puede realizar una actualización del estado de react en un componente no montado REACT-NATIVE

im construyendo un reproductor de música, así que quiero que cuando el usuario cierre la aplicación, guarde la posición de la canción que estaba escuchando, para hacer que yo sólo ejecute una función en el componenteWillUnmount en Track zone component, este:

 componentDidMount() {
        TrackPlayer.addEventListener("playback-track-changed", this.get_actual_track);
        TrackPlayer.addEventListener("playback-queue-ended", this.get_queue_option);
        this.init();
    }
  
   componentWillUnmount() {
      this.save_position();
   }

    save_position = async() => {
        status = await TrackPlayer.getState();
        console.log(status);
        if (status === 3 || status === 8 || status === 2) {
            let position = await TrackPlayer.getPosition();
            await AsyncStorage.setItem("last_song_duration", JSON.stringify(position));
            await TrackPlayer.pause();
            TrackPlayer.destroy();
        }else {
            return;
        }
    }

a veces lo ahorra, y a veces lo hace, piensa que tiene algo que ver con él, pero no sé qué, cuando abro la aplicación, este es el primer componente que carga todo:

en la aplicación Tengo Tab navigator

export default class App extends React.Component {

render() {} (Retorno) ■ ); } }

esto es tab navigator

   componentDidMount() {
    TrackPlayer.addEventListener("playback-track-changed", this.play_selected_music);
    this.requestPermission();
}

requestPermission = async () => {
    try {
        const permission = await PermissionsAndroid.requestMultiple(
            [
                PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
                PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
            ],
        );
        if (permission["android.permission.READ_EXTERNAL_STORAGE"] === PermissionsAndroid.RESULTS.GRANTED 
            && permission["android.permission.WRITE_EXTERNAL_STORAGE"] === PermissionsAndroid.RESULTS.GRANTED) {
            try {
                let tracks = [];
                let tracks_object = []; 
                tracks = await MusicFiles.getAll({
                    cover: true,
                });
                let length = tracks.length;
                for (i = 0 ; i < length ; i++) {
                    tracks_object.push(new Tracks_info(tracks.results[i]));
                }
                this.setState({tracks: tracks_object}, () => this.init_player());
            }catch(error) {
                alert(error);
            }
        }else {
            this.requestPermission();
        }
    }catch (error) {
        alert(error)
    }
};

init_player = async () => {
    
    try {
        if (this.random) {
            let tracks = this.random_queue();
            await TrackPlayer.setupPlayer();
            await TrackPlayer.updateOptions({ stopWithApp: true });
            await TrackPlayer.add(tracks);
            this.setState({random_tracks: tracks, init: true});
        }else {
            let tracks = this.state.tracks;
            await TrackPlayer.setupPlayer();
            await TrackPlayer.updateOptions({stopWithApp: true});
            await TrackPlayer.add(tracks);
            this.setState({init: true});
        }
    }catch(error) {
        alert(error);
    }
}

su método de renderización:

 
                    
                         }>
                         }>
                    
                     (this.sheetref = ref)}
                        initialSnap = {1}
                        snapPoints = {[Dimensions.get("window").height - StatusBar.currentHeight, 95]}
                        renderHeader = {() => }
                        renderContent = {() => }
                        enabledContentGestureInteraction = {false}
                        onOpenEnd = {this.hide_icon}
                        onCloseEnd = {this.show_icon}>
                    
   

Pregunta hecha hace 3 años, 4 meses, 27 días - Por bugbusterx


2 Respuestas:

  • El error "No se puede realizar una actualización del estado de React en un componente no montado" suele ocurrir cuando intentas actualizar el estado de un componente que ya ha sido desmontado, como en el caso de llamar a setState() en un componente que ya no está en la jerarquía de componentes. En tu caso, parece que el error puede estar relacionado con la llamada a this.save_position() en componentWillUnmount() del componente TrackZone.

    Una posible solución es asegurarte de que el componente TrackZone esté montado antes de llamar a save_position() en componentWillUnmount(). Puedes hacer esto agregando una bandera isMounted en el estado del componente y actualizándola en los métodos componentDidMount() y componentWillUnmount(). Luego puedes verificar esta bandera antes de llamar a save_position().

    Aquí te dejo un ejemplo de cómo podrías implementar esto:

    javascript
    export default class TrackZone extends React.Component {
        state = {
            isMounted: false
        };
    
        componentDidMount() {
            this.setState({ isMounted: true });
            TrackPlayer.addEventListener("playback-track-changed", this.get_actual_track);
            TrackPlayer.addEventListener("playback-queue-ended", this.get_queue_option);
            this.init();
        }
    
        componentWillUnmount() {
            this.setState({ isMounted: false });
            this.save_position();
        }
    
        save_position = async() => {
            if (!this.state.isMounted) {
                return;
            }
    
            const status = await TrackPlayer.getState();
            console.log(status);
            if (status === 3 || status === 8 || status === 2) {
                let position = await TrackPlayer.getPosition();
                await AsyncStorage.setItem("last_song_duration", JSON.stringify(position));
                await TrackPlayer.pause();
                TrackPlayer.destroy();
            } else {
                return;
            }
        }
    
        render() {
            // Tu lógica de renderizado aquí
        }
    }
    

    Con esta implementación, antes de llamar a save_position() en componentWillUnmount(), se verifica si el componente está montado. Esto debería ayudar a prevenir el error "No se puede realizar una actualización del estado de React en un componente no montado".

    Espero que esta solución te sea de ayuda. Si tienes más preguntas o dudas, no dudes en consultarme.

    Respondida el Dec 20, 2020 a las 16:51 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El error "No se puede realizar una actualización del estado de React en un componente no montado" ocurre cuando intentas actualizar el estado de un componente que ya no está montado. Esto puede suceder si el componente se desmonta antes de que se complete la actualización del estado.

    En tu caso, el componente TrackZone se desmonta cuando el usuario cierra la aplicación. Esto hace que la llamada a save_position() en componentWillUnmount() falle.

    Para resolver este problema, puedes intentar guardar la posición de la canción en componentDidMount() en lugar de componentWillUnmount(). Esto asegurará que la posición se guarde antes de que el componente se desmonte.

    También puedes intentar usar useEffect() para guardar la posición de la canción. useEffect() se ejecuta después de que el componente se haya montado, por lo que no tendrás que preocuparte de que el componente se desmonte antes de que se guarde la posición.

    Aquí tienes un ejemplo de cómo puedes usar useEffect() para guardar la posición de la canción:

    javascript
    useEffect(() => {
      const savePosition = async () => {
        status = await TrackPlayer.getState();
        console.log(status);
        if (status === 3 || status === 8 || status === 2) {
          let position = await TrackPlayer.getPosition();
          await AsyncStorage.setItem("last_song_duration", JSON.stringify(position));
          await TrackPlayer.pause();
          TrackPlayer.destroy();
        } else {
          return;
        }
      };
    
      savePosition();
    
      return () => {
        // Cleanup function
      };
    }, []);
    

    Espero que esto ayude.

    Respondida el Dec 20, 2020 a las 16:58 - por Gemini

    Votos positivos: 0 | Votos negativos: 0