Reputation: 141
I am navigatiing from /home to /listing/1 then from there I am navigating to /listing/2, when I go back I expect to go back to /listing/1 but it is going back to /home.
Why is that, If it is a dynamic route, expo router doesnt add it to the history and replaces it? How can I fix this?
This is my folder structre
this is my main layout:
<Stack>
<Stack.Screen
name="index"
options={{
headerShown: false,
}}
/>
<Stack.Screen
name="+not-found"
options={{
headerShown: false,
}}
/>
<Stack.Screen name="(auth)" options={{ headerShown: false }} />
<Stack.Screen name="(main)" options={{ headerShown: false }} />
<Stack.Screen name="listing/[id]" options={{ headerShown: false }} />
<Stack.Screen name="chef/[id]" options={{ headerShown: false }} />
<Stack.Screen name="category/[id]" options={{ headerShown: false }} />
</Stack>
This is my back button, but it still doesnt work if I slide back
import React from "react";
import { TouchableOpacity } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import { useRouter, useNavigation } from "expo-router";
interface BackButtonProps {
size?: number;
color?: string;
className?: string;
}
const BackButton: React.FC<BackButtonProps> = ({ size = 24, color = "gray", className = "" }) => {
const router = useRouter();
const navigation = useNavigation();
// Check if we can go back
const canGoBack = navigation.canGoBack();
return (
<TouchableOpacity
onPress={() => {
if (canGoBack) {
// Use router.back() if we can go back
router.back();
} else {
// If we can't go back, go to the home screen
router.replace("/");
}
}}
className={`rounded-full ${className}`}>
<Ionicons name="chevron-back" size={size} color={color} />
</TouchableOpacity>
);
};
export default BackButton;
Versions I use
"@react-navigation/native": "^6.0.2",
"expo-linking": "~7.0.4",
"expo-router": "~4.0.16",=
"react": "18.3.1",
"react-dom": "18.3.1",
"react-native": "0.76.6",
Upvotes: 0
Views: 316
Reputation: 3293
You can solve it by adding a getId
prop to the <Stack.Screen />
. For example:
<Stack.Screen
name="ad/[slug]"
options={{ headerShown: false }}
getId={({ params }) => params.slug}
/>
By default, the Stack navigator removes duplicate screens when pushing a route that is already in the stack. For example, if you push the same screen twice, the second push will be ignored. You can change this push behavior by providing a custom getId() function to the <Stack.Screen>.
Ref: https://docs.expo.dev/router/advanced/stack/#custom-push-behavior
Upvotes: 0
Reputation: 1
When navigating between /listing/1 and /listing/2, expo-router may replace the current route in the history stack instead of adding a new entry.
This happens because the route paths only differ by a dynamic id, which some configurations may treat as a single screen.
so When router.back() is called, it looks at the history stack. If the navigation history only has /home or /listing/2 (replacing /listing/1), it will go back to /home.
To avoid it u can use router.push(/whatever) to the stack. instead of router.replace(/whatever).
const navigateToListing = (id) => {
const router = useRouter();
router.push(`/listing/${id}`);
};
Upvotes: 0