I need to track some logs event(only once) when App launch and close.
First I do this in Home
screen componentDiMount()
, but it will be instantiated several times in some case, causing repetitive launch event log.
=============== Edit =================
AppState
can only listen background and active event.
When closing app on Android (press back key or close in recents app menu), it actually back to background. It takes the app back to active from background when reopen the app. Which is the same as toggle app between background and active(not close)
So I can't determine whether it is first launch or toggling app status using AppState
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'.
In React Native, AppState represents the current state of the app — i.e., whether the app is in the foreground or background. AppState is useful for collecting data on app usage — for example, the time a user spends in the app before putting it in the background or closing the app.
Currently, there is, unfortunately, no support for background tasks of any kind. The feature you are referring to would be a background timer. Such a timer is this product pain (a feature request) for react native, you may upvote it to show an increased demand for this feature.
In general, useEffect
with an empty dependency array is what you're looking for.
In React Native, code can be running when app state is not active, but useEffect
with an empty dependency array will be running on first app launch.
If you're using dependency values, you can use useRef
to track if it's handled in first app launch.
const onLaunchRef = React.useRef<boolean>();
useEffect(() => {
if (onLaunchRef.current) {
return;
}
doSomething(state1, state2);
onLaunchRef.current = true;
}, [state1, state2]);
You can combine this with useAppState:
import { useAppState } from '@react-native-community/hooks'
const onLaunchRef = React.useRef<boolean>();
const appState = useAppState();
useEffect(() => {
if (onLaunchRef.current) {
return;
}
if (appState !== 'active') {
return;
}
doSomething(state1, state2);
onLaunchRef.current = true;
}, [state1, state2, appState]);
You can use the following:
useEffect(() => {
return () => {
doSomething(state1, state2);
};
}, [state1, state2]);
Or use useAppState
:
const appState = useAppState();
useEffect(() => {
if (appState !== 'active') {
doSomething();
}
}, [appState]);
However, actual close event does not exist in React Native. This is somewhat tricky problem to handle.
Note: Following answer was written when OP didn't edit the question to add info about the limitations of AppState.
Using AppState
.
From Official Docs:
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>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With