简体   繁体   中英

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')

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.

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')}

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>
    );
  }
}

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 KS 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>
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM