Preventing hardware back button android for React Native
AndroidReact NativeAndroid Problem Overview
I want to prevent the user from going back to the previous screen. So I added code, but this does not work. Are there any solutions for this? The alert pop up is seen but "return false" does not work.
componentDidMount() {
BackAndroid.addEventListener('hardwareBackPress', () => {
Alert.alert("alert","alert")
this.props.navigator.pop();
return false;
});
Android Solutions
Solution 1 - Android
You need to return true, if you want to disable the default back button behavior.
Here is a sample component which will block the user from going back to previous screen.
import React, {Component,} from 'react';
import {
View,
Text,
BackHandler,
ToastAndroid,
} from 'react-native';
class BackButtonDemo extends Component {
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}
handleBackButton() {
ToastAndroid.show('Back button is pressed', ToastAndroid.SHORT);
return true;
}
render() {
return (
<View>
<Text>Back button example</Text>
</View>
);
}
}
module.exports = BackButtonDemo;
Note:
Also remove this.props.navigator.pop();
from your solution.
Navigator
pop function will take the user to the previous screen rendered by Navigator
.
Solution 2 - Android
Shiny new implementation using react hooks:
import React, {Component, useEffect} from 'react';
import {
View,
Text,
BackHandler,
} from 'react-native';
const LogInView = () => {
useEffect(() => {
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => true)
return () => backHandler.remove()
}, [])
return (
<View>
<Text>Back button example</Text>
</View>
);
}
export default LoginView
Solution 3 - Android
I disable my back button (android) for whole application by add this code in App.js
componentDidMount() {
BackAndroid.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
BackAndroid.removeEventListener('hardwareBackPress', this.handleBackButton);
}
handleBackButton() {
return true;
}
don't forget to import BackAndroid
import {BackAndroid} from 'react-native'
Solution 4 - Android
Try this Disable back button by just returning true
import {BackAndroid} from 'react-native';
componentWillMount() {
BackAndroid.addEventListener('hardwareBackPress', () => {return true});
}
Solution 5 - Android
Just to give you a complete answer when using react-navigation:
If you're using react-navigation, place the following in your RootNavigation class not the App.js in order to disable the back-button for the whole application.
import { BackHandler } from 'react-native';
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.onBackButtonPressed);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.onBackButtonPressed);
}
onBackButtonPressed() {
return true;
}
Solution 6 - Android
using the BackHandler from react native worked for me. Just include this line in your ComponentWillMount:
BackHandler.addEventListener('hardwareBackPress', function() {return true})
it will disable back button on android device.
Solution 7 - Android
If you are using react-natigation then you need to use BackHandler
instead of BackAndroid
import { BackHandler } from 'react-native';
// code
componentDidMount() {
BackHandler.addEventListener('backPress');
}
// some more code
componentWillUnmount() {
BackHandler.removeEventListener('backPress');
}
Solution 8 - Android
So While Everyone is working with the Backhandler of react-native I tried to do it with react-navigation to prevent going back handler. This worked for me. If you just want to prevent going back without showing or alerting anything to the user.
React.useEffect(() => {
navigation.addListener('beforeRemove', (e) => {
e.preventDefault();
});
}, [navigation]);
You can put this code in your function component.
Use Case:
> In User Registration when the user signup and go to the confirmation > screen for the code so we dont want him back you can use this code at > the moment.
Solution 9 - Android
Disable back button for module react-navigation, use hook useFocusEffect
const hardwareBackPressCustom = useCallback(() => {
return true;
}, []);
useFocusEffect(() => {
BackHandler.addEventListener('hardwareBackPress', hardwareBackPressCustom)
return () => {
BackHandler.removeEventListener('hardwareBackPress', hardwareBackPressCustom)
};
}, []);
Solution 10 - Android
For me, this was the solution:
import React, { useEffect } from 'react'
import { View } from 'react-native'
function Home({ navigation }) {
useEffect(() =>
navigation.addListener('beforeRemove', (e) => {
e.preventDefault();
return
}),
[navigation]
);
return (
<View>
...
</View>
)
}
export default Home
You can see an example in docs
Solution 11 - Android
Just an update for Version 6.x as seen in RN docs
function ScreenWithCustomBackBehavior() {
// ...
useFocusEffect(
React.useCallback(() => {
const onBackPress = () => {
if (isSelectionModeEnabled()) {
disableSelectionMode();
return true;
} else {
return false;
}
};
BackHandler.addEventListener('hardwareBackPress', onBackPress);
return () =>
BackHandler.removeEventListener('hardwareBackPress', onBackPress);
}, [isSelectionModeEnabled, disableSelectionMode])
);
// ...
}
Alternatively as a hook
import {useNavigation} from '@react-navigation/native';
import {useEffect, useState, useCallback} from 'react';
export const usePreventGoBack = () => {
const navigation = useNavigation();
const [allow, setAllow] = useState(false);
const beforeRemoveListener = useCallback(
e => {
if (allow) {
return;
}
e.preventDefault();
},
[allow],
);
useEffect(() => {
const unsub = navigation.addListener('beforeRemove', beforeRemoveListener);
return () => {
unsub();
};
}, [navigation, beforeRemoveListener, allow]);
return (cb: () => void) => {
setAllow(true);
setTimeout(() => {
cb();
});
};
};
To bypass
const continuePressed = () => {
allowBackButton(() => {
navigation.popToTop();
});
};
Solution 12 - Android
For IOS use this code... In the Stack Navigation. react-navigation > 5
<LoginStackNav.Screen name="Home" component={Home} options={{gestureEnabled: false }}/>
Solution 13 - Android
The only correct solution can be found here: https://reactnavigation.org/docs/custom-android-back-button-handling/
function ScreenWithCustomBackBehavior() {
// ...
useFocusEffect(
React.useCallback(() => {
const onBackPress = () => {
return true;
};
BackHandler.addEventListener('hardwareBackPress', onBackPress);
return () =>
BackHandler.removeEventListener('hardwareBackPress', onBackPress);
}, [isSelectionModeEnabled, disableSelectionMode])
);
// ...
}
All the others are for class components or apply to all screens, rather than only the screen where the hook is applied.
Solution 14 - Android
Onclick of hardware back button OnBackPressed callback gets called
you can just remove super declaration in onBackPressed call back.
@Override
public void onBackPressed() {
}