【问题标题】:Expo Tab Navigation and Stack NavigationExpo选项卡导航和堆栈导航
【发布时间】:2021-05-03 08:32:55
【问题描述】:

您好,我正在尝试在用户登录时添加选项卡导航,在用户未登录时添加堆栈导航。所以我写了一个逻辑,但我不知道为什么会出错。请帮帮我。

我只想在用户成功登录后显示选项卡导航我使用 Nodejs 后端和 Mongodb 作为数据库。

这是我的 AppNavigator 文件。

AppNavigator.js

import React, { useEffect, useState } from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
import { NavigationContainer } from '@react-navigation/native';
import SignUp from "../screens/SignupScreen";
import LoginScreen from "../screens/LoginScreen";
import LoadingScreen from "../screens/LoadingScreen";
import HomeScreen from "../screens/HomeScreen";
import AsyncStorage from '@react-native-async-storage/async-storage';
const Stack = createStackNavigator();

const Tab = createBottomTabNavigator()
const [isLoggedin, setLogged] = useState(null)
const TabNavigator = () => {
  return <TabNavigator>
    <Tab.Screen name='Home' component={HomeScreen} />
    <Tab.Screen name='Profile' component={AccountScreen} />
    <Tab.Screen name='Home' component={HomeScreen} />
  </TabNavigator>
}
const AuthNavigator = () => {
  return (
  <Stack.Navigator
    headerMode="none"
    screenOptions={{
      headerStyle: { elevation: 0 },
      cardStyle: { backgroundColor: '#fff' }
    }}
  >


    <Stack.Screen name="loading" component={LoadingScreen}></Stack.Screen>
    <Stack.Screen name="home" component={HomeScreen}></Stack.Screen>

    <Stack.Screen name="login" component={LoginScreen}></Stack.Screen>
    <Stack.Screen name="signup" component={SignUp}></Stack.Screen>


  </Stack.Navigator>
  )
};
const Navigation = () => {
  const [user, setUser] = useState('');
  useEffect(() => {
      if (isLoggedin) {
        setUser(userExist)
      }
      else {
        setUser('')
      }
    
  }, [])
  return (
    <NavigationContainer >
      {user ? <TabNavigator /> : <AuthNavigator />}
    </NavigationContainer>
  )
};
function AppNavigator() {

  useEffect(() => {
    const token = AsyncStorage.getItem('token')
    if (token) {
      setLogged(true)
    }
    else {
      setLogged(false)
    }
  }, [])
  return (
    <Navigation />
  );
}

export default AppNavigator;

这是我的 App.js 文件

App.js

import React,{useEffect,useState} from "react";
import { NavigationContainer } from "@react-navigation/native";
import AppNavigator from "./navigation/AppNavigator";

export default function App() {
  return (
      <AppNavigator />

  );
}

我有自己的 LoadingScreen 文件

LoadingScreen.js

import { StatusBar } from 'expo-status-bar';
import React,{useEffect,useState} from 'react';
import { StyleSheet, ActivityIndicator, Image,View,Text } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Button, TextInput } from 'react-native-paper';

// <View style={styles.container}>
export default function LoadingScreen(props) {
    
    const detectLogin = () =>{
        const token = AsyncStorage.getItem('token')
        if (token) {
            props.navigation.navigate("profile")
        }
        else {
            props.navigation.navigate("login")
        }
    }
    useEffect(() => {
       detectLogin()
      }, [])
    return (
        <View style={styles.container}>
        <ActivityIndicator size="large" color="black">
         
        </ActivityIndicator>
        </View>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
    },
  
});

【问题讨论】:

  • 你遇到了什么错误?

标签: javascript reactjs react-native expo react-native-tabnavigator


【解决方案1】:

我创建了一个Snack 供您查看工作示例

我注意到的第一件事是您在 TabNavigator 函数中编写了

return <TabNavigator>
    <Tab.Screen name='Home' component={HomeScreen} />
    <Tab.Screen name='Profile' component={AccountScreen} />
    <Tab.Screen name='Home' component={HomeScreen} />
  </TabNavigator>

你必须写这样的东西

return <Tab.Navigator> // Notice the . here
    <Tab.Screen name='Home' component={HomeScreen} />
    <Tab.Screen name='Profile' component={AccountScreen} />
    <Tab.Screen name='Home' component={HomeScreen} />
  </Tab.Navigator>

我猜你的令牌恢复逻辑效率不高。

我建议你制作两个不同的Navigators 并在你的App.js 中执行token checking 逻辑

您应该做的是,在您的App.js 所在的位置创建一个名为navigation 的文件夹。

然后在navigation里面创建两个文件AppNavigator.jsAuthNavigator.js

您的AppNavigator.js 应该是这样的 -

import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

import HomeScreen from '../screens/HomeScreen';
import AccountScreen from '../screens/AccountScreen';

const Tab = createBottomTabNavigator();

function AppNavigator() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Home" component={HomeScreen} />
      <Tab.Screen name="Accounts" component={AccountScreen} />
    </Tab.Navigator>
  );
}

export default AppNavigator;

你的AuthNavigator.js 应该是这样的 -

import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';

import LoadingScreen from '../screens/LoadingScreen';
import HomeScreen from '../screens/HomeScreen';
import LoginScreen from '../screens/LoginScreen';
import SignUp from '../screens/SignUpScreen';

const Stack = createStackNavigator();

function AuthNavigator() {
  return (
    <Stack.Navigator
      headerMode="none"
      screenOptions={{
        headerStyle: { elevation: 0 },
        cardStyle: { backgroundColor: '#fff' },
      }}>
      <Stack.Screen name="loading" component={LoadingScreen}></Stack.Screen>
      <Stack.Screen name="home" component={HomeScreen}></Stack.Screen>

      <Stack.Screen name="login" component={LoginScreen}></Stack.Screen>
      <Stack.Screen name="signup" component={SignUp}></Stack.Screen>
    </Stack.Navigator>
  );
}

export default AuthNavigator;

那么你应该从here安装expo-app-loading

然后在你的App.js

import React, { useEffect, useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import AppLoading from 'expo-app-loading';
import AsyncStorage from '@react-native-async-storage/async-storage';

import AppNavigator from './navigation/AppNavigator';
import AuthNavigator from './navigation/AuthNavigator';

export default function App() {
  const [user, setUser] = useState('');
  const [IsReady, setIsReady] = useState(false);

  const RestoreUser = async () => {
    const token = await AsyncStorage.getItem('token');
    if (token) {
      setUser(true);
    } else {
      setUser(false);
    }
  };

  if (!IsReady) {
    return (
      <AppLoading
        startAsync={RestoreUser}
        onFinish={() => setIsReady(true)}
        onError={() => {}}
      />
    );
  }

  return (
    <NavigationContainer>
      {user ? <AppNavigator /> : <AuthNavigator />}
    </NavigationContainer>
  );
}

这是我在所有项目中使用的最有效的身份验证方式..

【讨论】:

  • 再次感谢您帮助我解决了我的错误,但我在屏幕上看不到任何标签导航
  • 我在问题中添加了自己的 loadingScreen.js 文件
  • 它显示在那里,但它实际上发生得如此之快以至于你没有注意到它。
  • 你用过我的实现方式吗??如果是,那么您将看不到您的loading screen ,因为在恢复令牌时它使用AppLoading
  • 是的,我已按照您在此处提交的说明进行操作,并且我还检查了 Snack,我没有看到 Tab Navigator,在我的手机上它仅在时间可见,但在下一次刷新时可见它不见了。我希望底部的标签导航器在主屏幕和帐户屏幕上可见。
【解决方案2】:

显然我必须从我的代码中删除这两个才能正常工作,现在已经解决了。谢谢。

import { StatusBar } from 'expo-status-bar';

<StatusBar style="dark" backgroundColor="black" barStyle="light-content" />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 2018-08-21
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    相关资源
    最近更新 更多