Reload screen when react-native app is re-opened - react-native

In a react-native application, when we click on Home button the application is minimized. If after that I click on the application then application is resumed where it was minimized last. I want to refresh the last open screen every time that the application is maximized. What should I do to achieve this?
I tried {useIsFocused} from #react-navigation/native and I also tried
const unsubscribe = navigation.addListener('focus', () => {
alert('focus')
});
But it's not working.
Thanks in advance

Appstate is what you're looking for. Change componentDidMount to useEffect and state to useState if required. More info here
import {
AppState
} from 'react-native';
constructor(props) {
super(props)
this.state = {
appState: AppState.currentState
}
}
componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange);
}
_handleAppStateChange = (nextAppState) => {
if (
this.state.appState.match(/inactive|background/) &&
nextAppState === 'active'
) {
//Todo: Reload task here
}
this.setState({ appState: nextAppState });
};

Related

How to detect drawer notification in React Native?

I tried to use AppState from react-native with the blur listener but nothing is showing up. I did the same exact code https://reactnative.dev/docs/appstate but the blur listener is not working. I just want to know when the notification drawer (https://developer.android.com/guide/topics/ui/notifiers/notifications#bar-and-drawer) appear on my application screen
export default class AppStateExample extends Component {
state = {
appState: AppState.currentState
};
componentDidMount() {
AppState.addEventListener("blur", this._handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener("blur", this._handleAppStateChange);
}
_handleAppStateChange = nextAppState => {
console.log("test")
};
}
Thank s for help !

React Native - How to detect home button is pressed or not?

I can know when the scene is on screen using following code:
this.subs = [
this.props.navigation.addListener('didFocus', this.loadOfflineData)
];
But , if I want to detect when scene is out of focus. I 'm wondering what should I do .
Basically I want to detect if the user press home button and then I want to perform some action.
Any suggestions.
You can use AppState to know when an app is put into the background.
AppState can tell you if the app is in the foreground or background, and notify you when the state changes.
Here is a simple example of using AppState:
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!');
} else {
console.log('App has gone to the background!');
// start your background task here
}
this.setState({appState: nextAppState});
};
render() {
return <Text>Current state is: {this.state.appState}</Text>;
}
}
I've done this with android and java using the android lifecycle. This should work in React Native (see EDIT down below). the developer.android.com forum: this page
In short:
onCreate(): a user opens your app for the first time
onStart(): app restarts
onResume(): a user opens your app while it was active in the background
onPause(): app goes out of focus
onStop(): app is no longer visible
onDestroy(): activity will be destroyed
In your case you should use onPause()
So a little code snippet for in java:
#Override
public void onPause() {
super.onPause();
//do something
}
EDIT:
This answer tells you how to detect onPause and onResume in Reacte Native.
Code in that answer:
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>
);
}
}

Is it possible to check user's moving activity when app is in background or killed in react native?

We are working on realtime location sharing app, we have to run our job's when app is in background and if its moving, we need to get the location of the user.
Is there any possibility in react-native so that we can track the user moving activity(in background and killed states) and track location or run the background job ?
Try to listen for AppState changes and when your app goes in the background you should start doing what you want to do.
import { AppState } from 'react-native';
import BackgroundTimer from 'react-native-background-timer';
state = {
appState: AppState.currentState
}
In componentDidMount use this:
AppState.addEventListener('change', this._handleAppStateChange);
In componentWillUnmount :
AppState.removeEventListener('change', this._handleAppStateChange);
Use something like this function and you will get your result for when the app is in the background.
_handleAppStateChange = (nextAppState) => {
if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
console.log('App has come to the foreground!');
} else {
console.log('App is in background');
const interval = BackgroundTimer.setInterval(() => {
console.log('listen for location changes here');
if (this.state.appState === 'active') {
//Stop the interval when AppState goes
//back to active again
BackgroundTimer.clearInterval(interval);
}
}, 1000);
}
}
this.setState({ appState: nextAppState });
}

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');
}
}

React Native setInterval doubles it self after restarting app

All the time setInterval acts as I am expecting except for one instance. If user leaves the app by clicking 'home button' and restarts app by clicking the icon (not by selecting from overview), the old setInterval haven't stopped. It starts over again, and there are now running 2 setIntervals. It goes on and on if I repeat this process and user can end up running hundreds of intervals at the same time.
How do I prevent this? I want to run only one instance of seInterval at the time.
Here's my code:
import React, { Component } from 'react';
import {
AsyncStorage,
Text,
View,
AppState,
} from 'react-native';
import timer from'react-native-timer';
class Code_temp extends Component {
redirect(routeName){
this.props.navigator.push({
name: routeName
});
}
constructor(props){
super(props);
this.state = {
appState: AppState.currentState,
};
}
componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange);
this.setState({showMsg: true}, () => timer.setInterval(
this, 'hideMsg', () =>{
console.log( 1 );
}, 1000
));
}
componentWillUnmount() {
AppState.removeEventListener('change', this._handleAppStateChange);
}
_handleAppStateChange = (nextAppState) => {
if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
}
this.setState({appState: nextAppState});
};
componentWillMount() {
}
render() {
return (
<View>
<Text>
Test
</Text>
</View>
);
}
}
export default Code_temp
That's because you are not clearing the setInterval when the component is unmounted, also remove 'this' from setinterval arguments
componentDidMount() {
timer.clearInterval('hideMsg');
AppState.addEventListener('change', this._handleAppStateChange);
this.setState({showMsg: true}, () => timer.setInterval(
'hideMsg', () =>{
console.log( 1 );
}, 1000
));
}
componentWillUnmount() {
timer.clearInterval('hideMsg');
};