i need a help, i created the auth with react navigation v5 in react native, the auth is working, but when i login with navigation.navigate('Beranda')
in login form, i got the error, how to fix the error like this and here's my code
code function for login
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');
}
};
and here my code for navigation
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;
here's the error click here
thank you for helping me before.
The reason why you are getting that if because the screen is not part of the navigation. The easiest way to fix this is to unconditionally render all routes
return (
<NavigationContainer>
<AuthScreenStack/>
<BerandaScreen/>
</NavigationContainer>
);
This will always render the AuthScreenStack first. If you want to keep the user logged in (check localStorage for token), You will need to add logic to your AuthScreenStack to redirect to the BarandaScreen stack if the token exists already.
For automatically redirecting from the AuthScreenStack to BarandaScreen if the token exist, you can add the following to your 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();
}, []);
This code runs only once when the component mounts. Get the token from the local storage, then navigates to the Beranda screen.