(Yes)
(Yes)
react-native -v
:react-native-cli: 2.0.1
react-native: 0.47.1
node -v
:v8.1.3
npm -v
:5.0.3
yarn --version
:0.27.5
Then, specify:
react-native run-android
(Write your steps here:)
class App extends Component {
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.onBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
}
onBackPress = () => {
return true;
};
render() {
return (
<Text>Press back buton</Text>
);
}
}
If you run the code in development
environment , it don't works and when you press back button , app will be closed , but in development
environment if you turn on remote debug
, the code works well and app not closed
(Prevent closing app on back button pressed)
(On development
environment when remote debug
is off it don't woks but when remote debug
is on it works)
(N/A)
Any updates??
+1
Can you reproduce the issue using Snack? This step is necessary for people to be able to see and debug the issue being reported.
@hramos I explain in details how to reproduce the issue , I cannot reproduce the issue using Snack because there is no dev menu in Snack , so remote debug
is meanless
You can run the Snack within the Expo Client and shake the device to trigger a menu to show up, no?
In any case, this is a community project. To answer your "any updates?" question, we'd take a look at any PR that proposes a fix.
@hramos , I tried before using Expo Client , there is no dev menu , You can try it yourself
exp://expo.io/@snack/SJn2le4cZ
@sm2017 Is there a Symbol polyfill included by your app or any of your dependencies?
If you do, than this could be caused by issue #11968, which I have a PR to fix #15182.
Most desktop browsers support Symbol
natively, so that would explain why the issue doesn't show up in dev mode where the browser's JS engine is used instead of the mobile device's (which may not have a native Symbol implementation).
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. If you think this issue should definitely remain open, please let us know why. Thank you for your contributions.
Hi, I am having the same trouble with it.
I am trying to implement custom action for back button and I have added the code like the below.
But it's getting an event when I enable "Debug JS Remotely" but it's not getting an event when I disable it. What's up?
I am trying to implement that backbutton functionality and I am having trouble with that.
componentDidMount () {
ToastAndroid.show("Event` Listener added", ToastAndroid.SHORT);
BackHandler.addEventListener('hardwareBackPress', () => this.backAndroid())
}
componentWillUnmount () {
BackHandler.removeEventListener('hardwareBackPress', () => this.backAndroid())
}
backAndroid () {
ToastAndroid.show("Welcome", ToastAndroid.SHORT);
return true
}
@sm2017, have you resolved this issue?
@howilliams No
Everybody that have same issue , Please add a +1
comment here
Same issue here, is there any workaround ?
i met this issue too, when i open debugger,android back button works well to go back to the previous page,but when i close debugger or release a version ,press back button just lead to exit app.Pls help to solve this issue asap,thanks.
What i do:
i found the BackHandler.android.js in react-native ,the path is : "react-native/Libraries/Utilities/BackHandler.android.js"ïŒ test and found:
when i open debugger: subscriptions contains the function i wrote: this.onBackAndroid ïŒand the param invokeDefault is false. then it works well to goback to previous page.
when i close debugger: subscriptions is [] ,contains nothing ïŒand then the param invokeDefault is true.and then it lead to exitApp.
version:
"react-native": "0.46.1",
@Victoriayangx Please upgrade to 0.51, your likely encountering a bug that has already been fixed.
Hey, @dantman.
I found out that Version0.51 has some upgraded codes but it does not work at all.
It still doesn't work in normal mode, but it's working on 'Debug Only' mode and it's really really weird.
I have spent 2 days to track the issues and found out that it's the same on version 0.51.
I am gonna attach another screenshot when we run it in the 'Debug Mode'.
As you can see, in the debug mode, the Set are converted well to Array var but that doesn't work in normal mode.
HI, @sm2017. Have you found the round-about?
Hi @sm2017, I am facing the same issue. I am using React Navigation. When the remote debug mode is on, the back handler works perfectly,
After turning the remote debug off or in release mode of the app, the back handler doesn't work.
Have you found any way to fix this behavior?
I changed the source code in BackHandler.android.js,then it worked.
Background:
After redux integration with react-navigation,i also met this issue.
refer:https://reactnavigation.org/docs/guides/redux
SourceCode:(react-native/Libraries/Utilities/BackHandler.android.js)
`
RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function() {
var subscriptions = [];
var invokeDefault = true;
_backPressSubscriptions.forEach(item=>subscriptions.push(item));
for (var i = 0; i < subscriptions.length; ++i) {
if (subscriptionsăsubscriptions.length-1-iă()) {
invokeDefault = false;
break;
}
}
// var backPressSubscriptions = new Set(_backPressSubscriptions);
// var invokeDefault = true;
// var subscriptions = [...backPressSubscriptions].reverse();
// for (var i = 0; i < subscriptions.length; ++i) {
// if (subscriptionsi) {
// invokeDefault = false;
// break;
// }
// }
if (invokeDefault) {
BackHandler.exitApp();
}
});`
Bingo!!! This works.
Good job, @Victoriayangx .
Can you fork the repo and submit a merge request so that the developers all over the world would get updated one.
Hey Guys. For me, this issue for Back Handler was due to a react-native-pathjs-charts package that was being used. I created a new solution and added each package one by one and kept on testing.
Path js package stopped the back handler. ES6 syntax distribution for that package worked for me. I copied that files and add that to my component and used it from there.
Same package or some other package might have caused the same for you.
Hi Navneet,
Can you please explain me what exactly is to be done? I am using react-native-pathjs-charts in my project, so can you please explain me what is to be changed and where?
@Victoriayangx Thanks a ton!!! đ you are my saviour
@dantman ,
Hi, I suspect BackHandler cause App exit maybe caused by âArray.from(new Set())â.
Recently I met another issue about duplicate remove in Array.
1ăBy using "let newArray = Array.from(new Set( array ))" , in debug mode, the newArray shows ok ,when close debug mode or release mode, sometimes the newArray shows ok ,sometimes the newArray shows empty. it is not stable for App.
2ăBy using forEach & indexOf to remove the duplicate element in array, it always shows ok till now.
So,I suspect BackHandler cause App exit maybe also caused by ânew Setâ. So in Our React-Native Project, to achieve remove duplicate element in Array , we will not use new Set until the issue is resolved.
Hope it can help.Any advice,pls let me know.thanks.
@Victoriayangx You're basically describing the same things I researched when I had the issue: https://github.com/facebook/react-native/issues/11968#issuecomment-296543410
There's also a fair bit of comparison of various methods of iterating in the comments of my PR:
https://github.com/facebook/react-native/pull/15182
@dantman i get it, you are awesome.
@krunalpanchal
I was using the Radar graph from the react-native-paths-js.
Download the es6 folder from the below link:
https://github.com/andreaferretti/paths-js/tree/master/dist
Add a new folder in your components section in your app. Let us say, I added the folder named as Radar. Create a new folder named as charts inside the Radar folder. Copy all the files of the es6 folder to that chart folder.
Now create a new js file( CustomRadar.js in my case ) for the graph which you are using in the Radar folder. I was using Radar graph. So, I copied the Radar.js from the following link :
https://github.com/capitalone/react-native-pathjs-charts/tree/master/src
You can copy the type of js file based on the graph you are using. Now you have created your own path js library under the components folder.
In CustomRadar.js ( in my case), make sure all the references in that copied content are pointing to the same filenames under your Radar component. If your custom file requires any reference file which is not yet added to the Radar folder. Just add that file to your folder and the alter the reference path.
Make sure all the file references path are pointing to the custom files we added.
@Victoriayangx Is there any solution other than changing in the library because I am using Expo that won't allow me to make the change in the library.
Hi, I created a PR which fixes this issue. Maybe you can verify this this change and give a thump up for #19077.
This fix worked for me. https://github.com/facebook/react-native/issues/3223#issuecomment-355064410
This issue occurred for me when pulling in core-js/es6/symbol
in the app. Used es6-symbol
instead which does not seem to conflict with babel transforms
or JavascriptCore
which is where I think the issue is when core-js/es6/symbol
is imported.
[email protected]
supports Symbol
as far as I can tell but that throws another error, so can't really verify.
For other people the issue could be happening because the polyfill is being imported from a dependency, might be able to override how Symbol
is being pulled in by being explicit inrn-cli.config.js
.
still getting the problem and won't be able to change android folder because I'm using expo, please someone from RN, take one of the PRs here into consideration, really need it to work! :(
@Victoriayangx You are the great buddy.
Working like this in 54.2
var DeviceEventManager = require('NativeModules').DeviceEventManager;
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var DEVICE_BACK_EVENT = 'hardwareBackPress';
type BackPressEventName = $Enum<{
backPress: string,
}>;
var _backPressSubscriptions = new Set();
RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function () {
var invokeDefault = true;
var subscriptions = [];
// var subscriptions = Array.from(_backPressSubscriptions.values()).reverse();
_backPressSubscriptions.forEach(item => subscriptions.push(item));
for (var i = 0; i < subscriptions.length; ++i) {
if (subscriptionsi) {
invokeDefault = false;
break;
}
}
if (invokeDefault) {
BackHandler.exitApp();
}
});
Any updates on this? editing android folder shouldn't be the only way to fix this issue... it's unfair for CRNA/Expo users :$
@princepardeep isn't that code this workaround? https://github.com/facebook/react-native/issues/3223#issuecomment-355064410
I that have same issue, what is the solution?
it was working fine in my case.
change in this file
source code:(react-native/Libraries/Utilities/BackHandler.android.js)
Working like this in 54.2
var DeviceEventManager = require('NativeModules').DeviceEventManager;
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var DEVICE_BACK_EVENT = 'hardwareBackPress';
type BackPressEventName = $Enum<{
backPress: string,
}>;
var _backPressSubscriptions = new Set();
RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function () {
var invokeDefault = true;
var subscriptions = [];
// var subscriptions = Array.from(_backPressSubscriptions.values()).reverse();
_backPressSubscriptions.forEach(item => subscriptions.push(item));
for (var i = 0; i < subscriptions.length; ++i) {
if (subscriptionsi) {
invokeDefault = false;
break;
}
}
if (invokeDefault) {
BackHandler.exitApp();
}
});
@princepardeep this is the same code you already posted, and which is posted in https://github.com/facebook/react-native/issues/3223#issuecomment-355064410 ... you should avoid re-posting the same code.
But yes, it is frustrating, that this kind of bug still exists. But instead of fixing that inside the core-file, I've added this code to my main app class:
constructor(props){
super(props);
// https://github.com/facebook/react-native/issues/3223#issuecomment-355064410
this.backPressSubscriptions = new Set();
}
componentDidMount() {
if (Platform.OS === 'android') {
// there is a bug/workaround on android https://github.com/facebook/react-native/issues/3223#issuecomment-355064410
DeviceEventEmitter.removeAllListeners('hardwareBackPress');
DeviceEventEmitter.addListener('hardwareBackPress', () => {
let invokeDefault = true;
const subscriptions = [];
this.backPressSubscriptions.forEach(sub => subscriptions.push(sub));
for (let i = 0; i < subscriptions.reverse().length; i += 1) {
if (subscriptions[i]()) {
invokeDefault = false;
break;
}
}
if (invokeDefault) {
BackHandler.exitApp();
}
});
this.backPressSubscriptions.add(this.handleAndroidHardwareBack);
}
}
componentWillUnmount() {
if (Platform.OS === 'android') {
DeviceEventEmitter.removeAllListeners('hardwareBackPress');
this.backPressSubscriptions.clear();
}
}
I find it unfeasible for me to create multiple listening events in different components
There is still my 4 month old PR #19077 which fixes this... But nobody have the time to review/merge it. đ
@TranHanHieu @princepardeep @FibreFoX Maybe you can verify if this change works for you as well and upvote the PR?
oke, thanks you @jerolimov !
@tranhanhieu,
I created an HOC to handle android back button press, then just pass on a function I want to call... I donât actually have a viewable component to it, I return null, and then just add it to the bottom of each component I need it.
PR #19077 is merged and is finally part of the latest RN release 0.58+
I hope for all of you that this issue here is fixed when you upgrade your RN version. đ
Awesome! I'm going to close this for the time being, if the issue is still present please submit a new issue :)
Thanks @jerolimov!
Most helpful comment
@howilliams No
Everybody that have same issue , Please add a
+1
comment here