Reputation: 77
I want to be able to check if the user has notification permissions on or off every time the user opens the app from any state ( if the app was never opened before or the app was in the background etc.) What I have now is checking permissions via PushNotificationIOS.checkPermissions in the render function. However, with that method it keeps on being called and causes a memory leak. Another method I tried was whenever the user wants to be notified (via pressing an icon) the onPress method is called to check the perms but that causes the user to press the icon twice in order for the permission state to be updated.
import {
PushNotificationIOS,
AsyncStorage,
..
} from "react-native";
export default class Bell extends React.Component {
constructor(props) {
super(props);
this.state = {
isNotifActive: null,
isBellActive: false,
alertBody:"",
fireDate: null,
LaunchStatus: "",
ID:'',
timeSelected: ""
};
this.accessKeyNotif = `${this.props.fireDate}-isNotifActive`;
}
componentDidMount = () =>{
this.setState({
set props to state....
});
AsyncStorage.getItem(this.accessKeyNotif).then(value => this.setState({ isNotifActive: JSON.parse(value) }));
}
render() {
PushNotificationIOS.checkPermissions((permissions) => {
if (permissions.alert) {
AsyncStorage.setItem(this.accessKeyNotif, JSON.stringify(true)).then(() => {
this.setState({ isNotifActive: true});
});
}
else{
AsyncStorage.setItem(this.accessKeyNotif, JSON.stringify(false)).then(() => {
this.setState({ isNotifActive: false});
});
}
});
return (
<Ionicons
name={this.state.isBellActive? "md-notifications":"md-notifications-off"}
color={"white"}
size={30}
style={styles.NotifIcon}
onPress={() => {
if(this.state.isNotifActive){
Make a notification
}
else if(!this.state.isNotifActive){
Cancel Notifications
}
}}
/>
);
}
}
The Bell component is called on multiple times (20 times) by another class in order to display the bell.
Upvotes: 1
Views: 676
Reputation: 28539
You shouldn't be performing that check in the render
method as each setState
will cause a re-render, meaning to multiple unnecessary re-renders. It would be better handling this using an AppState
listener. The following code will call _handleAppStateChange
whenever the app comes into the foreground, goes into the background.
You can import it from react-native like so
import { AppState } from 'react-native'
Then in your component
state = {
appState: AppState.currentState, // set the currentState as the appState
};
componentDidMount () {
// Set the listener
AppState.addEventListener('change', this._handleAppStateChange);
}
componentWillUnmount () {
// remove the listener
AppState.removeEventListener('change', this._handleAppStateChange);
}
_handleAppStateChange = (nextAppState) => {
if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
// app has come to the foreground
// perform checks etc here
}
// update the appState
this.setState({ appState: nextAppState });
}
You can read more about it here https://facebook.github.io/react-native/docs/appstate
Upvotes: 1