Maki
Maki

Reputation: 319

React Native Logout inside a DrawerNavigator

I want to navigate back from DrawerNav to Login. Using alert('Alert') inside the function is OK.

I have a StackNavigator with Login and DrawerNav

const MyStackNavigator = StackNavigator({
  Login : { screen : Login },
  DrawerNav : { screen : DrawerNav }
  }, {
    navigationOptions : { header : false }
  }
);

From Login i can navigate to my main screen DrawerNav using

_login = () => {
  this.props.navigation.navigate('DrawerNav');
}

Inside the DrawerNav is a DrawerNavigator (obviously)

const MyDrawerNavigator = DrawerNavigator({
    ... screens ...
  }, {
    initialRouteName : '',
    contentComponent : CustomContent,
    drawerOpenRoute : 'DrawerOpen',
    drawerCloseRoute : 'DrawerClose',
    drawerToggleRoute : 'DrawerToggle'
  }
);

const CustomContent = (props) => (
    <View>
      <DrawerItems {...props} />
      <TouchableOpacity
        onPress={ this._logout }>
        <Text style={ styles.logout }>Logout</Text>
      </TouchableOpacity>
   </View>
)

As you can see, the logout is not part of the menu but inside the Drawer

_logout = () => {
  this.props.navigation.navigate('Login');
}

This gives me an error

undefined is not an object (evaluating '_this.props.navigation')

Upvotes: 8

Views: 3033

Answers (4)

robincEPtion
robincEPtion

Reputation: 47

NOTE: Best practice to implement auth screens is by using switch navigator. If you're supposed not to use it for some reason, the following stuffs could help.

1: As @Asrith K S answered, change your functional component to class component and write _logout as class function, where this.props would have navigation

(or)

2: write navigate action as anonymous function.

const CustomContent = (props) => (
  <View>
    <DrawerItems {...props} />
    <TouchableOpacity
      onPress={ () => props.navigation.navigate("Login") }>
      <Text style={ styles.logout }>Logout</Text>
    </TouchableOpacity>
  </View>
)

Upvotes: 0

Ashrith K S
Ashrith K S

Reputation: 490

Change your customComponent to class component from functional.Like..

class CustomContent extends Component {
  _logout = () => {
    const resetAction = NavigationActions.reset({
      key: null,
      index: 0,
      actions: [NavigationActions.navigate({ routeName: 'Login' })],
    });
    this.props.navigation.dispatch(resetAction);
  }
  render() {
    return (
      <View>
        <DrawerItems {...props} />
        <TouchableOpacity
          onPress={this._logout}
        >
          <Text style={styles.logout}>Logout</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

Upvotes: 0

Andrew
Andrew

Reputation: 28539

As you are quite deep in your navigation stack wouldn't it make sense to use the popToTop function?

In the same file make sure that you define your _logout function as your CustomContent, then you could do something like the following:

  1. Update the function call by passing props to them
  2. Update _logout to use popToTop()

Here is how my code would look.

_logout = (props) => {
  props.navigation.popToTop();
}

const CustomContent = (props) => (
    <View>
      <DrawerItems {...props} />
      <TouchableOpacity
        onPress={ () => this._logout(props) }>
        <Text style={ styles.logout }>Logout</Text>
      </TouchableOpacity>
   </View>
)

You will want to pass the props to the function as that will contain your navigation prop and allow you to make calls on your navigation stack.

Upvotes: 1

Roy Wang
Roy Wang

Reputation: 11260

Problem

The this in this._logout is meant for referencing a CustomContent instance, but since CustomContent is a functional component (which doesn't have instances), any this reference shouldn't be valid but is not throwing an error due to a bug.

Solution

Change

onPress={this._logout}

to

onPress={() => props.navigation.navigate('Login')}

Upvotes: 0

Related Questions