react-nativereact-navigationtabnavigator

Getting route name from tab navigation


I want to get the name of the current route to disable the hardware back button only in the screen Home (below). So I want to get the name of current screen. If it's 'Home', the hardware back button is disabled. If not, do nothing.


componentWillMount = () => {
    var currentScreen = this.props.navigation.state.routeName;

    if(currentScreen === 'Home'){
        BackHandler.addEventListener('hardwareBackPress', () => true);
    }
  }

  render(){
    return(
)}

But I get this error:

TypeError:undefined is not an object (evaluating '_this.props.navigation.state.routeName'

What can I do to fix it? If you guys have suggestions of blocking the back button, I would accept.

update

I did this:

    constructor(props) {
      super(props);
      this.onBackClicked = this._onBackClicked.bind(this);
    }
  
    componentWillUnmount() {
      BackHandler.removeEventListener('hardwareBackPress', this.onBackClicked);
    }
  
    _onBackClicked = () => {
      return true;
    };
  
    render() {
      return (
        <Tab.Navigator barStyle={{ backgroundColor: 'rgba(8, 0, 122, 0.91)'}}
          screenOptions={({route}) => {
            if (route.name === 'Home') {
            
            Alert.alert(route.name);

              BackHandler.addEventListener(
                'hardwareBackPress',
                this.onBackClicked,
              );
            } else {
              BackHandler.removeEventListener(
                'hardwareBackPress',
                this.onBackClicked,
              );
            }
          }}>

And I put an Alert to see the route name, but it brings me nothing. I suppose that's what troubles me.

By now I just have it:

export default class TabNavigator extends Component {
  constructor(props) {
      super(props);
      this.onBackClicked = this._onBackClicked.bind(this);
    }
  
    componentWillUnmount() {
      BackHandler.removeEventListener('hardwareBackPress', this.onBackClicked);
    }
  
    _onBackClicked = () => {
      return true;
    };
  
    render() {
      return (
        <Tab.Navigator barStyle={{ backgroundColor: 'rgba(8, 0, 122, 0.91)'}}
          screenOptions={({route}) => {
            if (route.name === 'Home') {
              BackHandler.addEventListener(
                'hardwareBackPress',
                this.onBackClicked,
              );
            } else {
              BackHandler.removeEventListener(
                'hardwareBackPress',
                this.onBackClicked,
              );
            }
          }}>

        <Tab.Screen name="Home" component={Home} options={{tabBarIcon: ({ tintColor }) => (
            <Icon name="home" size={30} color="rgb(253, 234, 223)" />
          ),}}/>    
     )
  }
}

Solution

  • You can do something like this:

    class TabNavigator extends Component {
      constructor(props) {
        super(props);
        this.onBackClicked = this._onBackClicked.bind(this);
      }
    
      componentWillUnmount() {
        BackHandler.removeEventListener('hardwareBackPress', this.onBackClicked);
      }
    
      _onBackClicked = () => {
        return true;
      };
    
      render() {
        return (
          <Tab.Navigator
            barStyle={{backgroundColor: 'rgba(8, 0, 122, 0.91)'}}
            screenOptions={({navigation, route}) => {
              if (route.name === 'Home' && navigation.isFocused()) {
                BackHandler.addEventListener(
                  'hardwareBackPress',
                  this.onBackClicked,
                );
              } else if (route.name !== 'Home' && navigation.isFocused()) {
                BackHandler.removeEventListener(
                  'hardwareBackPress',
                  this.onBackClicked,
                );
              }
            }}>
            <Tab.Screen
              name="Home"
              component={Home}
              options={{
                tabBarIcon: ({tintColor}) => (
                  <Icon name="home" size={30} color="rgb(253, 234, 223)" />
                ),
              }}
            />
            <Tab.Screen name="Settings" component={SettingsScreen} />
          </Tab.Navigator>
        );
      }
    }
    

    I use the route prop to get the current name and navigation.isFocused() to check if the current route name is "Home". If this is the case I add the event that disables the hardware back button. If the route name is not home, but it is focused the I remove the event listener. Lastly I remove the event listener when the component unmounts to prevent memory leaks.