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 !
Related
I am new to react native. I want To refresh or reload whole screen automatically. when user enter in that screen. Then screen will instantly reload or refresh automatically. So how to do that in react native. is possible . if yes please help.
if I write That logic in componentDidMount Will it reload screen. if yes then How to write that in componentDidMount below.
componentDidMount () {
BackHandler.addEventListener('hardwareBackPress',()=> this.handleBackButtonClick(), false);
}
An often-used hack in React is to change the key prop of your component to force a re-mount of a view:
import { BackHandler } from 'react-native';
class APP extends React.Component {
constructor(props) {
super(props)
this.handleBackButtonClick = this.handleBackButtonClick.bind(this);
}
state = {
uniqueValue: 1;
}
componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButtonClick);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButtonClick);
}
handleBackButtonClick() {
this.forceRemount();
return true;
}
forceRemount = () => {
this.setState({uniqueValue: this.state.uniqueValue + 1});
}
render() {
return (
<View key={this.state.uniqueValue}>
<Button onPress={this.forceRemount} />
</View>
)
}
}
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 });
};
Is it possible to get a callback on click of home and recent apps buttons of the device?
Although we can handle back, I want to handle the others too I searched but couldn't find any way for this one.
Thanks in Advance
We have no callback for this event, but you can use the lifecycle methods to detect when user click button home
Below is an example from App state
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(/active/) &&
nextAppState === 'background'
) {
console.log('user click button home');
}
this.setState({appState: nextAppState});
};
render() {
return <Text>Current state is: {this.state.appState}</Text>;
}
}
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>
);
}
}
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');
}
}