Undo backpress reacts to the router's own flow
I am using react native router thread in my native application. I want to override the back button click event as I want to add a confirmation popup before returning. I searched a lot, but all the links I found were for overriding a hardware button on an Android button press. Not only do I want to override the hardware click event, but I also want to override the click event of the back button on the navigation bar (for Android and iOS). Please help me here.
Edit: I found one way to undo the second click by adding two props in my scene back
and onBack
. But now the problem is that I want this inverse to be conditional. I am passing a boolean prop to edit
this scene. If the edit is true, then only I want to override the opposite, otherwise I just want to use the default. So how can I change the Scene parameter in my Router.js using the props passed to this scene?
sudo code
if(edit){
openConfirmationDialog();
} else {
Actions.pop();
}
source to share
The solution by @Raj Suvariya was covered for me above, but only if I added a renderBackButton callback for the scene whose "onBack" I wanted to customize (the "Home" scenario in Raj's example): So this was added to the scene definition:
renderBackButton={()=>{}}
And this was added when navigating the page, just like in Raj above:
Actions.Home({onBack: () => console.log('custom back callback') });
source to share
React Native | react-native-router-stream | Redux | Back button listener on Android, manual press on android when using native reaction.
// below code works with Android + react native + react-native-router-flux
// this is final index.js file code from where control whole app navigation
import { BackHandler, ToastAndroid } from 'react-native';
import React,{Component} from 'react';
import { Router, Scene, Actions } from 'react-native-router-flux';
import { Provider } from 'react-redux';
// as per your compoenents import them accordingly
import Home from './home';
import OtherScreen from './OtherScreen';
//variable
var backButtonPressedOnceToExit = false;
export default class App extends Component {
componentWillMount(){
BackHandler.addEventListener('hardwareBackPress', this.onBackPress.bind(this));
}
componentWillUnmount(){
BackHandler.removeEventListener('hardwareBackPress', this.onBackPress.bind(this));
}
onBackPress() {
if (backButtonPressedOnceToExit) {
BackAndroid.exitApp();
} else {
if (Actions.currentScene !== 'Home') {
Actions.pop();
return true;
} else {
backButtonPressedOnceToExit = true;
ToastAndroid.show("Press Back Button again to exit",ToastAndroid.SHORT);
//setting timeout is optional
setTimeout( () => { backButtonPressedOnceToExit = false }, 2000);
return true;
}
}
}
render() {
return(
<Provider store={store}>
<Router backAndroidHandler={this.onBackPress} >
<Scene key="root" }>
<Scene key="Home" component={Home} initial={true} />
<Scene key="OtherScreen" component={OtherScreen} />
</Scene>
</Router>
</Provider>
);
}
}
AppRegistry.registerComponent('YourAppNameAccordingToPackageJSON', () => App);
source to share
onBack
with this problem, but I didn't add onBack
to props like Raj's post, if you have a lot of places to override it will be very frustrating to add the onBack props. What I do is overwrite the default RNRF with the onBackPress function.
//App.js
<Router
scenes={scenes}
createReducer={reducerCreate}
getSceneStyle={getSceneStyle}
backAndroidHandler={() => {
let cs = Actions.currentScene;
if (cs === 'sc1' || cs === 'sc2') {
} else {
// default, pop back
Actions.pop();
}
return true;
}}
/>
//component1.js, "component1" is a key in scenes registered.
handleBackAction = () => {
if (Actions.currentScene === "component1") {
// do something you want and return true to intercept back event.
return true;
}
return false;
}
componentDidMount() {
this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackAction);
}
componentWillUnmount() {
this.backHandler.remove();
}
source to share