skip to Main Content

I am using react-native-router-flux as my navigator. The issue that I am facing is probably quite simple but I can’t seem to put my head into it. When the user logins in to the app, he/she gets redirected to the main dashboard scene. From there, if the user presses the android back button, the app should logically close instead of navigating back to the login screen again but I can’t grasp the missing logic for achieving this.

Router:

import React, { Component } from 'react'
import {
  TouchableOpacity
} from 'react-native'
import { Scene, Router, Actions } from 'react-native-router-flux'
import Login from '../pages/login'
import Dashboard from '../pages/dashboard'
import NavigationDrawer from './navigationDrawer'
import Icon from 'react-native-vector-icons/MaterialIcons';

const Menu = () => {
  return(
    <TouchableOpacity
      onPress={ () => Actions.refresh({key: 'drawer', open: value => !value }) }>
      <Icon
        name="view-headline"
        size={30}
        color="white"
      />
    </TouchableOpacity>
  )
}

class NavigationRouter extends Component {

  render() {
    return(
      <Router>
        <Scene initial key="login" component={Login} hideNavBar/>
        <Scene key="drawer" component={NavigationDrawer} open={false} >
          <Scene key="main">
            <Scene initial key="dashboard" title="Dashboard" navigationBarStyle={Styles.navigationBarStyle} component={Dashboard} hideNavBar={false}
              renderLeftButton={() => (<Menu/>)} />
          </Scene>
        </Scene>
      </Router>
    )
  }
}

const Styles = {
  navigationBarStyle: {
    backgroundColor: "#fda21d"
  }
}
export default NavigationRouter;

Dashboard Scene:

import React, {Component} from 'react'
import {
  View,
  Text,
  BackAndroid
} from 'react-native'
import {Actions} from 'react-native-router-flux'
import Icon from 'react-native-vector-icons/MaterialIcons'

class Dashboard extends Component {
  constructor(props) {
    super(props)
    BackAndroid.addEventListener('hardwareBackPress', function() {
      if (this.props.title === 'Dashboard') {
        console.log("pressed");
      }
    })
  }
  render() {
      [...]
  }

I tried using the BackAndroid API that Facebook provided but it is also not working at all.

2

Answers


  1. Chosen as BEST ANSWER

    Reason I am answering my question even though Vinayr's one is marked as correct is only because I wrote it a tad bit differently (without Redux).

    In my navigation router I added a reducer function as mentioned in the accepted answer and I aslo added the BackAndroid function there.

    Code:

    const reducerCreate = params => {
        const defaultReducer = Reducer(params);
        return (state, action) => {
            switch (action.type) {
              case ActionConst.FOCUS:
                if (action.scene.name === "dashboard") {
                  BackAndroid.addEventListener('hardwareBackPress', function() {
                    return BackAndroid.exitApp()
                  })
                }
                break;
              default:
                return;
            }
            return defaultReducer(state, action);
        }
    };
    
    class NavigationRouter extends Component {
    
      render() {
        return(
          <Router createReducer={reducerCreate}>
          [...]
      }
    

  2. This is how I did in my app using redux.

    componentWillMount() {
      BackAndroid.addEventListener('hardwareBackPress', this._backAndroid);
    }
    
    componentWillUnMount() {
      BackAndroid.removeEventListener('hardwareBackPress', this._backAndroid);
    }
    
    _backAndroid = () => {
      if (this.props.scene !== "home") {
        try {
          Actions.pop();
          return true;
        } catch(err) {
          return false; // exit app without prompt
        }
      }
    
      Alert.alert(
        'Exit',
        'Are you sure you want to exit?',
        [
          { text: 'Cancel', onPress: () => {} },
          { text: 'Yes', onPress: () => {BackAndroid.exitApp()}},
        ]
      );
      return true;
    }
    

    my reducer

    import { ActionConst } from 'react-native-router-flux';
    
    const initialState = {
      scene: {},
    };
    
    export default function reducer(state = initialState, action = {}) {
      switch (action.type) {
        // focus action is dispatched when a new screen comes into focus
        case ActionConst.FOCUS:
          return {
            ...state,
            scene: action.scene.name,
          };
        default:
          return state;
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search