How to detect when a React Native app is closed (not suspended)?

MobileReactjsReact Native

Mobile Problem Overview


I have looked everywhere and cannot find an answer to this. How can I detect when a user is trying to close my React Native app (as in the process is running, and they manually manage their apps and force exit it). I would like to add logout functionality when this happens, however cannot find a way to detect it. AppState appears to only detect when the app is brought in and out of the background.

Mobile Solutions


Solution 1 - Mobile

Looks like you can detect the previous state and compare it to the next state. You can't detect that the app is closing vs going into the background, from what I can find online, but you can detect if it was inactive (closed), or in the background.

Example from [React Native Docs][1]

import React, {Component} from 'react'
import {AppState, Text} from 'react-native'

class AppStateExample extends Component {

  state = {
    appState: AppState.currentState
  }

  componentDidMount() {
    AppState.addEventListener('change', this._handleAppStateChange);
  }

  componentWillUnmount() {
    AppState.removeEventListener('change', this._handleAppStateChange);
  }

  _handleAppStateChange = (nextAppState) => {
    if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
      console.log('App has come to the foreground!')
    }
    this.setState({appState: nextAppState});
  }

  render() {
    return (
      <Text>Current state is: {this.state.appState}</Text>
    );
  }

}

[1]: https://facebook.github.io/react-native/docs/appstate.html "React Native Docs"

Solution 2 - Mobile

I suggest to use web socket and it will help you to solve your problem, as following :

react native app

import React from 'react';
const io = require('socket.io-client/dist/socket.io');

const App = ()=>{
    React.useEffect(()=>{
        // connect to web socket
        window.appSocket = io.connect(`<server-origin>/?token=<string>&userAppId=<string>`);
        window.appSocket.on('connect',()=>{
            // do what you line
        })
    },[])

    ...
}
export default App; 

express server side

const express   = require('express');
const server    = express();
const http      = require('http').Server(server);
const io        = require('socket.io')(http);
io.on('connection',(socket)=>{ // this callback function for each web socket connection
    let { token , userAppId } = socket.handshake.query;
    if( userAppId ){ 
        console.log(`${userAppId} online`)
        socket.on('disconnect',(resean)=>{
            console.log(`${userAppId} shut down`)
        })
    }
});

for more details, you can check socket.io

Solution 3 - Mobile

Just ran into this same issue. The answer that's accepted does not actually do what is asked in the OP.

A hacky solution would be to set a flag on the first screen your application opens when opened fresh and to NOT SHOW THAT SCREEN when the app has just been backgrounded.

Not super elegant and I can't show example code, but it fixes my particular issue.

Solution 4 - Mobile

With @react-native-community/hooks you can use the useAppState hook to check the app state.

When you close the app, it gets a state of unknown once you open it back. When is in background, it says background' or 'inactive'. So when it's unknown` you know the app is opening from being closed, not minimized or in the background.

Solution 5 - Mobile

As a simple method , we can use componentWillUnmount() inside the root component for detect the app is closed. Because Root component Unmount only when app is closed. :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDale_PlanteView Question on Stackoverflow
Solution 1 - Mobileuser888750View Answer on Stackoverflow
Solution 2 - Mobilelaith mohammedView Answer on Stackoverflow
Solution 3 - Mobileblueberry_chopsticksView Answer on Stackoverflow
Solution 4 - MobileHelloView Answer on Stackoverflow
Solution 5 - MobileRidView Answer on Stackoverflow