This is my router.
<Router>
<Scene key="root" hideNavBar>
<Scene key="start" hideNavBar>
<Scene key="splash" component={Splash} initial />
<Scene key="startapp" component={AppStart} />
</Scene>
<Scene key="Drawer" drawer hideNavBar contentComponent={SideBar}>
<Scene key="main" hideNavBar>
<Scene key="home" component={Home} title="Main" initial />
<Scene key="payment" component={Payment} title="Pricing" />
<Scene key="vacuum" component={Vacuum} title="Vacuum" />
<Scene key="iron" component={Iron} title="Iron" />
<Scene key="dry" component={Dry} title="Dry" />
<Scene key="history" component={History} title="History" />
<Scene key="settings" component={Settings} title="Setiing" />
<Scene key="notipay" component={Notipay} title="Notipay" />
<Scene key="usernoti" component={UserNoti} title="UserNoti" />
</Scene>
</Scene>
<Scene key='EmpDrawer' drawer hideNavBar contentComponent={EmpSideBar}>
<Scene key="EmpMain" hideNavBar>
<Scene key="empoyee" component={Employee} title="Employee" initial />
<Scene key="settings" component={Settings} title="Setiing" />
</Scene>
</Scene>
<Scene key="auth" hideNavBar>
<Scene key="welcome" component={Welcome} title="Welcome To WashClean" initial />
<Scene key="login" component={Login} title="Please Login" />
<Scene key="register" component={Register} title="Register" />
<Scene key="privacy" component={Privacy} title="Privacy" />
<Scene key="terms" component={Terms} title="Terms" />
</Scene>
</Scene>
</Router>
Go to Drawer or auth :
Actions.Drawer({type: ActionConst.RESET});
Actions.auth({type: ActionConst.RESET});
Handle back button :
componentDidMount () {
BackHandler.addEventListener('hardwareBackPress', this.onBackPress);
}
componentWillUnmount () {
BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
}
onBackPress () {
if (Actions.state.index === 0) {
return false;
}
Actions.pop();
return true;
}
onBackPress return false but my app nothing happen.
same thing happens to me
+1
I found solution, just use BackHandler.exitApp() instead of return false
My code :
constructor(props) {
super(props);
this.state = {
doubleBackToExitPressedOnce: false
}
}
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
}
onButtonPress = () => {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton);
// then navigate
// navigate('NewScreen');
}
handleBackButton = () => {
if(this.state.doubleBackToExitPressedOnce) {
BackHandler.exitApp();
}
ToastAndroid.show('Press back again to exit', ToastAndroid.SHORT);
this.setState({ doubleBackToExitPressedOnce: true });
setTimeout(() => {
this.setState({ doubleBackToExitPressedOnce: false });
}, 2000);
return true;
}
Actual solution is to use backAndroidHandler in <Router> and return false only in home scene to exit.. you can get current scene by Actions.currentScene
As a workaround, you can get a hold of the action and test for 'Navigation/BACK' in the reducer. Then you can call BackHandler.exitApp(). Obviously, this solution is sub optimal but it does work if you're stuck as the listener doesn't fire but the events are still coming through the reducer.
Here is the reducer from the sample project amended for this purpose:
const reducerCreate = params => {
const defaultReducer = new Reducer(params);
return (state, action) => {
if(action.type === 'Navigation/BACK' && state.index === 0){
BackHandler.exitApp()
}
console.log('ACTION:', action);
return defaultReducer(state, action);
};
};
Officially, I don't recommend this but I didn't find any other way to make it happen.
as @vishnuc said, add this in your Router code :
onBackPress() {
if (Actions.state.index === 0) {
return false
}
Actions.pop()
return true
}
...
...
<Router backAndroidHandler={this.onBackPress}>
Then, the backButton will be handled by the library and if you want to do a specific action in a component with the backButton, it will override the onBackPress function.
Like this :
import { BackHandler} from 'react-native'
...
...
componentWill/DidMount() {
this.homeBackPressHandler = BackHandler.addEventListener('homeBackPress', () => {
if (Actions.currentScene === 'home' && myCondition) {
doStuff()
return true
}
return false
})
}
componentWillUnmount() {
this.homeBackPressHandler.remove()
}
Doing that in my Android app, never had a problem.
I'm having an issue with exiting the app when navigation from other screens work on initial load though.
https://stackoverflow.com/questions/47898965/exist-app-when-clicked-back-on-home-screen
Hope this will help : https://gist.github.com/Abhishekgarg727/447727a32e284c24346ec6d1a83feefe
I found solution, just use BackHandler.exitApp() instead of return false
My code :constructor(props) { super(props); this.state = { doubleBackToExitPressedOnce: false } } componentDidMount() { BackHandler.addEventListener('hardwareBackPress', this.handleBackButton); } componentWillUnmount() { BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton); } onButtonPress = () => { BackHandler.removeEventListener('hardwareBackPress', this.handleBackButton); // then navigate // navigate('NewScreen'); } handleBackButton = () => { if(this.state.doubleBackToExitPressedOnce) { BackHandler.exitApp(); } ToastAndroid.show('Press back again to exit', ToastAndroid.SHORT); this.setState({ doubleBackToExitPressedOnce: true }); setTimeout(() => { this.setState({ doubleBackToExitPressedOnce: false }); }, 2000); return true; }@dreamteryst how can this be made to work when there's an app drawer? My challenge is that subsequent screens continue to see Home screen, as this.props.navigation.state.routeName === 'Home'.
@dreamteryst Blapi
as @vishnuc said, add this in your Router code :
onBackPress() { if (Actions.state.index === 0) { return false } Actions.pop() return true } ... ... <Router backAndroidHandler={this.onBackPress}>Then, the backButton will be handled by the library and if you want to do a specific action in a component with the backButton, it will override the onBackPress function.
Like this :
import { BackHandler} from 'react-native' ... ... componentWill/DidMount() { this.homeBackPressHandler = BackHandler.addEventListener('homeBackPress', () => { if (Actions.currentScene === 'home' && myCondition) { doStuff() return true } return false }) } componentWillUnmount() { this.homeBackPressHandler.remove() }Doing that in my Android app, never had a problem.
aaaa. thank you! I half a day could not find a solution!
Most helpful comment
as @vishnuc said, add this in your Router code :
Then, the backButton will be handled by the library and if you want to do a specific action in a component with the backButton, it will override the onBackPress function.
Like this :
Doing that in my Android app, never had a problem.