How to remove item from AsyncStorage before closing react native app - react-native

How I can remove item from AsyncStorage when I close react native app?.
app.js:
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') {
AsyncStorage.removeItem('item');
console.log("App has come to the foreground!");
}
this.setState({ appState: nextAppState });
}
I never see something in the console.log

you can use same componentWillUnmount to do that as well
componentWillUnmount() {
AsyncStorage.removeItem('item');
AppState.removeEventListener('change', this.handleAppStateChange);
}
assuming this file is root js file and will unmount only when app closed

You don't need the AppState for this Use Case. You can remove the AsyncStorage Item in componentWillUnmount.
componentWillUnmount() {
AsyncStorage.removeItem('item');
}

Related

Can we perform location based task when app is terminated in react-native?

Is there a way by which we can perform location based task (geofence) in background when the app is killed.
componentDidMount() {
AppState.addEventListener('change',
this.handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener('change', this.handleAppStateChange);
}
handleAppStateChange = (nextAppState) => {
if (nextAppState === 'inactive') {
// Here you can do anything like Geolocation or logging
}
}

Cant Remove Event Listener App State React Native

I try to using app state listener in multiple screen. But it seems not remove listener properly.
In my case, I have app state listener in Home screen and Order Screen. App state listener in Home screen is not remove properly.
This is my app state listener in Home screen,
const _handleAppStateChange = (nextAppState) => {
appState.current = nextAppState
setAppStateVisible(appState.current)
if (nextAppState === 'active') {
checkConnection()
}
}
React.useEffect(() => {
AppState.addEventListener('change', _handleAppStateChange)
checkConnection()
return () => {
AppState.removeEventListener('change', _handleAppStateChange)
}
}, [])
This is my app state in Order Screen,
const _handleAppStateChange = async (nextAppState) => {
appState.current = nextAppState
setAppStateVisible(appState.current)
if (nextAppState === 'active') {
permissionFirebaseIos
}
}
React.useEffect(() => {
AppState.addEventListener('change', _handleAppStateChange)
return () => {
AppState.removeEventListener('change', _handleAppStateChange)
}
}, [])
What is wrong with my code?
You can with useFocusEffect hook from react navigation
https://reactnavigation.org/docs/use-focus-effect/
Its the same as useEffect but when the screen get focused/defocused
import { useFocusEffect } from '#react-navigation/native';
function YourScreen() {
useFocusEffect(
React.useCallback(() => {
AppState.addEventListener('change', _handleAppStateChange)
return () => AppState.removeEventListener('change', _handleAppStateChange);
}, [])
);
}

React Native stop animation when leaving the app

I have an Animated.timing and I want to stop it when the user navigate to another app, is this possible?
you can use AppState like this:
import React, {Component} from "react"
import {AppState, View} from "react-native"
class YourClass extends Component {
state = {
appState: AppState.currentState
}
componentDidMount() {
//add a listener here
AppState.addEventListener("change", this._handleAppStateChange);
}
componentWillUnmount() {
// remember add this line
AppState.removeEventListener("change", this._handleAppStateChange);
}
_handleAppStateChange = (nextAppState) => {
if (this.state.appState.match(/inactive|background/) && nextAppState === "active"){
console.log("App has come to the foreground!")
}else{
//here you can call stop animation function
}
this.setState({appState: nextAppState});
}
render() {
return (
<Text>Current state is: {this.state.appState}</Text>
);
}
}

BackHandler after changing app state doesn't invoke subscribed function

Steps to reproduce:
press home hardware button (app state is changing to background)
open app and try press back button
Expected result: handleBackButtonClick is invoked
Actually result: handleBackButtonClick isn't invoked
My code:
import { BackHandler } from 'react-native';
componentWillMount() {
AppState.addEventListener('change', this.handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener('change', this.handleAppStateChange);
}
handleAppStateChange = (state: AppStateStatus) => {
if (state === 'active') {
console.log('LISTEN');
BackHandler.addEventListener('hardwareBackPress', this.onBackPress);
} else {
console.log('UNLISTEN');
BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
}
};
handleBackButtonClick = () => {
console.log('press back')
this.props.navigation.goBack(null);
return true;
}
I am a little unsure what you are trying to accomplish but based on the react-native documentation on BackHandler, you may want to place the eventListener on componentDidMount to be safe. Your handler generally would then decide how to back E.g.
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
}
handleBackPress = () => {
this.goBack(); // works best when the goBack is async
return true;
}
Also, unless defined somewhere else this.onBackPress would be undefined in your context.

React-Native : change state when app is in background

I create a simple app that using React Native AppState:
import React, {Component} from 'react'
import {AppState, Text , View} from 'react-native'
export default class AppStateExample extends React.Component {
constructor(props){
super(props);
this.state = {
name:'not change'
}
}
componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener('change', this._handleAppStateChange);
}
_handleAppStateChange = (nextAppState) => {
if(AppState.currentState=='background'){
console.log('background mode');
this.setState({name:'back'});
}
if(AppState.currentState =='active'){
//...
}
};
render() {
return (
<View>
<Text>State Name : {this.state.name}</Text>
</View>
);
}
}
And when I try switch app from foreground to background and then background to foreground console.log('background mode'); work very well and console
print 'background mode'
BUT
The this.setState({name:'back'}); not working and I see 'not change' text in view
Actually, based on React Native Docs on AppState change for Functional Component I prefer to write code like below:
import { useRef, useState, useEffect } from "react";
import { AppState } from "react-native";
const AppStateManager = () => {
const appState = useRef(AppState.currentState);
const [appStateVisible, setAppStateVisible] = useState(appState.current);
useEffect(() => {
AppState.addEventListener("change", handleAppStateChange);
return () => {
AppState.removeEventListener("change", handleAppStateChange);
};
}, []);
const handleAppStateChange = (nextAppState) => {
if (
appState.current.match(/inactive|background/) &&
nextAppState === "active"
) {
console.log("App has come to the foreground!");
}
appState.current = nextAppState;
setAppStateVisible(appState.current);
console.log("AppState", appState.current);
};
return null;
};
export default AppStateManager;
Surely, we can use this component in the root of the project just like a React Component:
~~~
<App>
~~
<AppStateManager />
~~
.
.
.
It is because, AppState.addEventListener('change', this._handleAppStateChange); is too late to register.
You probably want to listen AppState the first thing in your app before main components get loaded and pass down the values probably by your state management library
I would go for a switch that wrap all endPoint
note: to get appState status AppState.currentState
this.state = {
appState: AppState.currentState
// https://facebook.github.io/react-native/docs/appstate.html
};
componentWillMount() {
AppState.addEventListener('change', () => this._handleAppStateChange());
};
componentWillUnmount() {
AppState.removeEventListener('change', () => this._handleAppStateChange());
}
_handleAppStateChange() {
// https://facebook.github.io/react-native/docs/appstate.html
const {
appState
} = this.state;
console.warn({
appState
})
this.fetchData().catch(error => error);
switch (appState) {
case 'active': //The app is running in the foreground
this.onStart();
break;
case 'background': // The app is running in the background. The user is either
this.onEnd();
console.warn('background');
break;
case 'inactive':
// The app transitioning between foreground & background or entering the Multitasking view or in the event of an incoming call
console.warn('Inactive');
break;
default:
console.warn('_handleAppStateChange default');
}
}