Just started learning React Native (using expo)
I have a profile.jsx in my app folder. It has multiple sub-menu. Each sub-menu also has a custom “<- Go Back” button which takes to profile.jsx.
File structure:
folder app has:
-
index.jsx
-
profile.jsx
-
home.jsx
-
(auth) folder
-
(profileMenu) folder
-
(category) folder
-
product folder
(auth) has _layout, signIn, login, guest and register jsx files
(profileMenu) has _layout, Favourites, Wallet, Payment, Settings, etc. also all jsx files.
In profile.jsx I have clickable menu items of (profileMenu) which on click go to that particular jsx file.
The <- go back button inside the files themselves work as intended but when using android Hardware back button the page goes back to through all the profileMenu items I have clicked through instead of going back to the default page which is profile.jsx.
Then further once I am on profile.jsx and I click on another profileMenu option (other than the first clicked option) and use the HW back button it takes me to that first clicked file instead of profile.jsx.
I have tried both router.push() and router.replace(). Both show the same bug.
BUT I have a menu item this does not happen with- Logout. I click on it any number of items it does not show this bug. If I click on first, go back and click on another menu item, I am successfully able to go back to profile and the logout page does not appear.
My logout button takes me to another folder (auth) which contains a few other files like signIn.jsx guest.jsx. In all of these files the HW back button takes to the previous page like it should
I will attach the necessary snippets from all the relevant files and also attach an image of my file structure. Please do help me.
/app/ _layout.jsx:
import { Ionicons } from "@expo/vector-icons";
export default function Layout() {
return (
<Tabs
screenOptions={{
headerShown: false,
}}
>
<Tabs.Screen
name="profile"
options={{
title: "Profile",
}}
/>
<Tabs.Screen
name="(auth)"
options={{
href: null,
}}
/>
<Tabs.Screen
name="(profileMenu)"
options={{
href: null,
}}
/>
</Tabs>
);
}
profile.jsx ->
//other imports etc.
const profile = () => {
const router = useRouter();
const handleMenuPress = (label) => {
const menuItems = [
{ icon: 'percent', label: 'Promotions', },
{ icon: 'settings',label: 'Settings', },
{ icon: 'log-out', label: 'Logout', },
];
console.log(`Pressed: ${label}`);
switch (label) {
case 'Promotions':
router.push('/(profileMenu)/Promotions');
break;
case 'Settings':
router.push('/(profileMenu)/Settings');
break;
case 'Logout':
router.replace('/(auth)/signIn');
break;
default:
console.log('Unknown menu item');
}
}
return (
//other profile options line name etc...
{/* Menu Items */}
<ScrollView>
<View>
{menuItems.map((item, index) => {
const IconComponent = item.iconSet;
return (
<TouchableOpacity
key={index}
onPress={() => handleMenuPress(item.label)}
>
<Text>{item.label}</Text>
</TouchableOpacity>
);
})}
</View>
</ScrollView>
);
};
;
export default profile
Promotions.jsx:
//imports
import { useRouter } from 'expo-router';
const Promotions = () => {
const router = useRouter();
const navigateToProfile = () => {
router.replace('/profile');
};
return (
<View>
<View>
<TouchableOpacity
onPress={navigateToProfile}
>
<Text style={styles.backButtonText}>← Back</Text>
</TouchableOpacity>
<Text style={styles.title}>Payments</Text>
</View>
<Text>Promotions</Text>
</View>
)
}
export default Promotions
Settings.jsx:
//imports plus :
import { useRouter } from 'expo-router';
const Settings = () => {
const router = useRouter();
const navigateToProfile = () => {
router.replace('/profile');
};
return (
<View>
<View>
<TouchableOpacity
onPress={navigateToProfile}
>
<Text>← Back</Text>
</TouchableOpacity>
<Text>Settings </Text>
</View>
<Text>
Settings
</Text>
</View>
)
}
export default Settings
in (profileMenu) folder: _layout.jsx:
import { Stack } from 'expo-router';
export default function ProfileLayout() {
return (
<Stack
screenOptions={{
headerShown: false,
}}
>
<Stack.Screen name="Promotions" />
<Stack.Screen name="Settings" />
<Stack.Screen name="Wallet" />
</Stack>
);
}
(auth) _layout.jsx
export default function AuthLayout() {
return (
<Stack
screenOptions={{
headerShown: false,
}}
>
<Stack.Screen name="signIn" />
<Stack.Screen name="login" />
<Stack.Screen name="register" />
<Stack.Screen name="guest" />
</Stack>
);
}
signIn.jsx:
//imports
import { router } from 'expo-router';
const { width, height } = Dimensions.get('window');
const SignIn = () => {
const menuItems = [
{ id: 1, label: 'login', text: 'Login to Your Account' },
{ id: 2, label: 'register', text: 'Create an Accound' },
{ id: 3, label: 'guest' },
]
const handleMenuPress = (label) => {
if (label === 'login') {
router.push('/(auth)/login');
} else if (label === 'register') {
router.push('/(auth)/register');
} else if (label === 'guest') {
router.push('/(auth)/guest');
}
};
return (
<SafeAreaView>
<ScrollView >
<View >
<Text >Sign in to continue shopping</Text>
</View>
<View >
<View>
<TouchableOpacity
onPress={() => handleMenuPress(menuItems[0].label)}
>
<Text>{menuItems[0].text}</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => handleMenuPress(menuItems[1].label)}
>
<Text>{menuItems[1].text}</Text>
</TouchableOpacity>
</View>
<TouchableOpacity
onPress={() => handleMenuPress('guest')}
>
<Text >Continue as Guest</Text>
</TouchableOpacity>
</View>
</ScrollView>
</SafeAreaView>
)
}
export default SignIn;
File Structure:
I have tried replacing the whole file twice, I have tried using router.push() as well as router.replace(). Both of them did not work. But for some reason logout menu item works.
I have replaced the _layout.jsx in both (auth) and (profileMenu) twice.
I am unsure at this point why my HardWare back Button is not functioning correctly.