使用 React Navigation V5 进行身份验证,单击按钮无法定向时出错

Auth with React Navigation V5, getting error when click button can't direct

我需要帮助,我在 react native 中使用 react navigation v5 创建了 auth,auth 工作正常,但是当我在登录表单中使用 navigation.navigate('Beranda') 登录时,出现错误,如何解决这样的错误,这是我的代码 登录代码函数

  const [body, setBody] = useState({
    username: '',
    password: '',
  });

  const _handleSubmit = () => {
    if (body.username === 'admin' && body.password === 'admin123') {
      AsyncStorage.setItem('username', 'admin');
      navigation.navigate('Beranda');
    } else {
      Alert.alert('Login Gagal');
    }
  };

这是我的导航代码

const HomeStackScreen = () => {
  return (
    <HomeStack.Navigator initialRouteName="Daily Transaction">
      <HomeStack.Screen name="DailyTransaction" component={DailyTransaction} />
      <HomeStack.Screen
        name="DetailTransaction"
        component={DetailTransaction}
      />
    </HomeStack.Navigator>
  );
};

const CashierStack = createStackNavigator();
const CashierStackScreen = () => {
  return (
    <CashierStack.Navigator initialRouteName="Menu">
      <CashierStack.Screen name="Menu" component={Menu} />
      <CashierStack.Screen name="DetailMenu" component={DetailMenu} />
      <CashierStack.Screen name="Cart" component={Cart} />
    </CashierStack.Navigator>
  );
};

const AuthStack = createStackNavigator();
const AuthScreenStack = () => {
  return (
    <AuthStack.Navigator headerMode="none">
      <AuthStack.Screen name="Login" component={Login} />
    </AuthStack.Navigator>
  );
};

const MenuBottom = createBottomTabNavigator();
const MenuBottomNav = () => {
  return (
    <MenuBottom.Navigator
      screenOptions={({route}) => ({
        tabBarIcon: ({focused, color, size}) => {
          if (route.name === 'Transaksi') {
            if (focused) {
              return (
                <Image
                  source={require('../../../assets/icons/wallet-gold.png')}
                  // eslint-disable-next-line react-native/no-inline-styles
                  style={{width: 25, height: 25}}
                />
              );
            } else {
              return (
                <Image
                  source={require('../../../assets/icons/wallet-white.png')}
                  // eslint-disable-next-line react-native/no-inline-styles
                  style={{width: 25, height: 25}}
                />
              );
            }
          } else if (route.name === 'Cashier') {
            if (focused) {
              return (
                <Image
                  source={require('../../../assets/icons/cash-gold.png')}
                  // eslint-disable-next-line react-native/no-inline-styles
                  style={{width: 25, height: 25}}
                />
              );
            } else {
              return (
                <Image
                  source={require('../../../assets/icons/cash-white.png')}
                  // eslint-disable-next-line react-native/no-inline-styles
                  style={{width: 25, height: 25}}
                />
              );
            }
          }
        },
      })}
      tabBarOptions={{
        activeTintColor: '#ffd700',
        inactiveTintColor: '#fff',
        style: {
          backgroundColor: '#000',
        },
      }}>
      <MenuBottom.Screen name="Transaksi" component={HomeStackScreen} />
      <MenuBottom.Screen name="Cashier" component={CashierStackScreen} />
    </MenuBottom.Navigator>
  );
};

const BerandaStack = createStackNavigator();
const BerandaScreen = () => {
  return (
    <BerandaStack.Navigator headerMode="none">
      <BerandaStack.Screen name="Beranda" component={MenuBottomNav} />
    </BerandaStack.Navigator>
  );
};

// const Stack = createStackNavigator();

const Main = () => {
  const [Loading, setLoading] = React.useState(true);
  const [token, setToken] = React.useState(null);
  React.useEffect(() => {
    const retrieveData = async () => {
      try {
        const valueString = await AsyncStorage.getItem('username');
        // Other set states
        setToken(valueString);
      } catch (error) {
        console.log(error);
      }
    };
    retrieveData();
  }, []);

  React.useEffect(() => {
    setTimeout(() => {
      setLoading(false);
    }, 4000);
  }, []);

  if (Loading) {
    return <Splash />;
  }
  return (
    <NavigationContainer>
      {token ? <BerandaScreen /> : <AuthScreenStack />}
    </NavigationContainer>
  );
};

export default Main;

这是错误 click here

谢谢你之前对我的帮助

你之所以会得到那个,是因为屏幕不是导航的一部分。解决这个问题的最简单方法是无条件渲染所有路由

return (
    <NavigationContainer>
      <AuthScreenStack/>
      <BerandaScreen/> 
    </NavigationContainer>
  );

这将始终首先呈现 AuthScreenStack。如果您想让用户保持登录状态(检查 localStorage 中的令牌),您需要向 AuthScreenStack 添加逻辑以在令牌已经存在的情况下重定向到 BarandaScreen 堆栈。

为了在令牌存在时自动从 AuthScreenStack 重定向到 BarandaScreen,您可以将以下内容添加到您的 AuthScreenStack:

React.useEffect(() => {
    const retrieveData = async () => {
      try {
        const valueString = await AsyncStorage.getItem('username');
        // Other set states
        // maybe you want to validate it first
        if (valueString) navigation.navigate('Beranda');
      } catch (error) {
        console.log(error);
      }
    };
    retrieveData();
  }, []);

此代码仅在组件安装时运行一次。从本地存储获取令牌,然后导航到 Beranda 屏幕。