'Preventing hardware back button android for React Native
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;
});
Solution 1:[1]
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:[2]
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:[3]
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:[4]
Try this Disable back button by just returning true
import {BackAndroid} from 'react-native';
componentWillMount() {
BackAndroid.addEventListener('hardwareBackPress', () => {return true});
}
Solution 5:[5]
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:[6]
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:[7]
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:[8]
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:[9]
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:[10]
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:[11]
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:[12]
For IOS use this code... In the Stack Navigation. react-navigation > 5
<LoginStackNav.Screen name="Home" component={Home} options={{gestureEnabled: false }}/>
Solution 13:[13]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow