使用 react Native DrawerNavigator 注销

Posted

技术标签:

【中文标题】使用 react Native DrawerNavigator 注销【英文标题】:Logout using react Native DrawerNavigator 【发布时间】:2018-06-15 02:45:17 【问题描述】:

我正在构建一个 react-native 应用程序 (App Image),它在 Drawer Navigator 上有注销链接。

代码如下

 const DrawerScreen = DrawerNavigator(
    ..........
    logout: 
        screen: Component   
    ,
)

export default DrawerScreen;

但问题是,它只是加载组件屏幕。我需要调用一个方法,我可以在其中执行 Asyncstorage clear 并导航到 LoginPage。

【问题讨论】:

【参考方案1】:

这是一种使用 react-navigation 库在抽屉中实现注销的方法。

<Drawer.Screen
    name="Logout"
    component=<Any Dummy Component>
    listeners=( navigation ) => ( 
        state: (e) => 
           if (e.data.state.index === 3) 
              // 3 is index of logout item in drawer

              navigation.replace("Login")
           
        
    )
/>

【讨论】:

只需使用身份验证流程文档中显示的内容,而不是做这些 hacky 的事情 reactnavigation.org/docs/auth-flow @satya164 使用 Drawer Navigator,文档中未提供如何执行操作。这就是为什么我需要使用这个解决方案。如果您使用抽屉导航器找到更好的解决方案,请告诉我。即使在 react-navigation git 问题中,这个问题也是可用的,但没有人提供适当的解决方案。 github.com/react-navigation/react-navigation/issues/7753 要退出,请调用文档中已定义的“signOut”函数 @satya164 即使调用signOut,你也需要监听器。您能否详细说明我可以在哪里调用“signOut”方法。如果你能在此处添加任何代码 sn-p 那就太好了。 我不确定为什么需要监听器。关于“where”,您可以在应该注销的按钮的“onPress”方法上调用它。要在抽屉中添加这样的按钮,有关于如何在抽屉中添加自定义按钮的文档:reactnavigation.org/docs/drawer-navigator#drawercontent【参考方案2】:

如果您正在导航版本 5 和功能组件中寻找答案:

  const getActiveRouteState = function (
    routes: Route<string>[],
    index: number,
    name: string
  ) 
    return routes[index].name.toLowerCase().indexOf(name.toLowerCase()) >= 0;
  ;

function CustomDrawerContent(
    props: DrawerContentComponentProps<DrawerContentOptions>
  ) 
    return (
      <View style= flex: 1 >
        <DrawerContentScrollView ...props>
          <View>
            <DrawerItem
              icon=( color, size ) => <Icon type='AntDesign' name='home' />
              label='Home'
              focused=getActiveRouteState(
                props.state.routes,
                props.state.index,
                'Home'
              )
              onPress=() => 
                props.navigation.navigate('Home');
              
            />
            <DrawerItem
              icon=( color, size ) => (
                <Icon type='AntDesign' name='minuscircle' />
              )
              label='Test'
              focused=getActiveRouteState(
                props.state.routes,
                props.state.index,
                'Test'
              )
              onPress=() => 
                props.navigation.navigate('Test');
              
            />
            <DrawerItem
              icon=( color, size ) => (
                <Icon type='AntDesign' name='logout' />
              )
              label='LogOut'
              onPress=async () => 
                await logoutUser();
                setLogginState(false);
              
            />
          </View>
        </DrawerContentScrollView>
      </View>
    );
  

      const AppDrawer = createDrawerNavigator();
      const AppDrawerScreen = () => (
        <AppDrawer.Navigator
          drawerPosition='left'
          drawerContent=(props) => <CustomDrawerContent ...props />
        >
          <AppDrawer.Screen
            name='Home'
            component=HomeScreen
            options= drawerLabel: 'Home' 
          />
          <AppDrawer.Screen name='Test' component=TestScreen />
        </AppDrawer.Navigator>
      );

如果您想在抽屉中隐藏选项,这也将有所帮助。

【讨论】:

【参考方案3】:
import StyleSheet,AsyncStorage,Alert, View,SafeAreaView, Text, ActivityIndicator, Dimensions, TextInput,Image, TouchableOpacity, TouchableHighlight from 'react-native';
import DrawerItems,DrawerActions from 'react-navigation-drawer';

 
            contentComponent:(props) => (
              <View style=flex:1>
                <SideMenu ...props/>
                    <DrawerItems ...props />
                    <TouchableOpacity onPress=()=>
                      Alert.alert(
                        'Log out',
                        'Do you want to logout?',
                        [
                          text: 'Cancel', onPress: () => this.props.navigation.dispatch(DrawerActions.closeDrawer()) ,
                          text: 'Confirm', onPress: () => 
                            AsyncStorage.clear();
                            props.navigation.navigate('LoginScreen')
                          ,
                        ],
                         cancelable: false 
                      )
                    >
                      <Text style=margin: 16,fontWeight: 'bold',color: 'red'>Logout</Text>
                    </TouchableOpacity>
              </View>
            ),
            drawerOpenRoute: 'DrawerOpen',
            drawerCloseRoute: 'DrawerClose',
            drawerToggleRoute: 'DrawerToggle'
    ,

【讨论】:

工作正常此代码用于反应导航版本 4。我尝试了很多示例,这是对我最有效的示例@Keshav Gera【参考方案4】:

您可能想在抽屉中添加一个按钮。 如果是这样,您的代码将如下所示。

const Drawer = DrawerNavigator(

    mainpage:screen:MyScreen
,

    contentComponent:(props) => (
        <View style=flex:1>
            <SafeAreaView forceInset= top: 'always', horizontal: 'never' >
                <DrawerItems ...props />
                <Button title="Logout" onPress=DO_SOMETHING_HERE/>
            </SafeAreaView>
        </View>
    ),
    drawerOpenRoute: 'DrawerOpen',
    drawerCloseRoute: 'DrawerClose',
    drawerToggleRoute: 'DrawerToggle'
)

您应该导入 import DrawerItems from 'react-navigation'; 以使其工作。

更新:

    在 4.x 版本的 react-navigation 中,您应该从 'react-navigation-drawer' 导入 `import DrawerNavigatorItems 您应该从 'react-native-safe-area-view' 导入 SafeAreaView

【讨论】:

在 onPress 中,如何将用户导航回登录页面?我似乎无法访问那里的导航道具。 @praveahjain props.navigation TypeError: TypeError: TypeError: undefined is not an object (evalating 'items.map') 点击 onPress 后出现上述错误 @BrightLee 嘿,如果我想创建一个带有图标作为前一个元素的服装样式名称,像这样 =>“◘ Logout”,如何处理这些 警告:React.createElement:类型无效——需要一个字符串(对于内置组件)或一个类/函数(对于复合组件),但得到:%s.%s%s,未定义,您可能忘记从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。收到此错误【参考方案5】:
const DrawerNavigation = createDrawerNavigator(
  
    Mainpage: 
      screen: Mainpage
    
  ,
  
    contentComponent:(props) => (
      <View style=flex:1>
          <SafeAreaView forceInset= top: 'always', horizontal: 'never' >
            <DrawerItems ...props />
            <TouchableOpacity onPress=()=>
              Alert.alert(
                'Log out',
                'Do you want to logout?',
                [
                  text: 'Cancel', onPress: () => return null,
                  text: 'Confirm', onPress: () => 
                    AsyncStorage.clear();
                    props.navigation.navigate('Login')
                  ,
                ],
                 cancelable: false 
              )  
            >
              <Text style=margin: 16,fontWeight: 'bold',color: colors.textColor>Logout</Text>
            </TouchableOpacity>
          </SafeAreaView>
      </View>
    ),
    drawerOpenRoute: 'DrawerOpen',
    drawerCloseRoute: 'DrawerClose',
    drawerToggleRoute: 'DrawerToggle'
  
);

【讨论】:

你应该 import import DrawerItems from 'react-navigation';让它工作。 不只是给出代码,如果你解释为什么它是答案会更有帮助。【参考方案6】:

只需使用 AlertView bro,这会有所帮助,但在上面的示例中,如果您有一个比这个 (this.props.navigation.navigate('LoginPage')) 的标题(this.props.navigation.navigate('LoginPage'))

没有任何意义

您的视图将加载到标题下方

【讨论】:

【参考方案7】:

您可以创建一个模式来为您执行此操作。单击注销 -> 使用可见属性显示模式并单击“是”然后关闭模式 -> 导航到登录屏幕。

【讨论】:

【参考方案8】:

您可以使用组件类来执行异步存储清除和导航登录页面。如果你使用 react-navigation this.props 有导航对象。

class YourComponent extends Component 
    constructor(props) 
        super(props);
     

    componentWillMount() 
        Asyncstorage.clear();
        this.props.navigation.navigate('LoginPage')
    

export default YourComponent;

【讨论】:

谢谢。但我不想默认加载组件。单击注销链接时,我需要显示一个带有“是”和“否”的确认框。然后点击“是”后,它应该加载组件。

以上是关于使用 react Native DrawerNavigator 注销的主要内容,如果未能解决你的问题,请参考以下文章

在另一个 React-Native 库中使用 React-Native 库

更新 react-native 后无法使用 react-native-debugger

React Native 速成 002 — 使用 UI框架 React Native Elements

React Native:对原生依赖使用自动链接“react-native-maps”

在 expo 中运行使用 react-native-cli 创建的 react-native 应用程序

使用 React-native-ble-plx 配置 React-native