Being a beginner with ReactJS trying to build a react-native app, I saw that expo was a good option to go about it. But for some reason, I can’t figure out a good way to use expo-router
from the documentation.
I’m not exactly sure how much information would be required to receive any help, but I will first write about my folder structure, then how the screens look like. Finally, I will also write down parts of the code. Please let me know if anything else is required for this problem.
My folder structure looks like this:
app/
├── settings/
│ ├── _layout.tsx
│ ├── index.tsx
│ └── auth/
│ ├── _layout.tsx
│ ├── index.tsx
│ ├── login.tsx
│ └── signup.tsx
├── _layout.tsx
├── [missing].tsx
├── chat.tsx
└── index.tsx
As expo-router
is a file-based routing system, I expect the screens to stack like Home -> Settings -> Auth
, but when I go from the Home
screen to Settings
page, and then from there move to the Auth
page, somehow the back button still takes me back to Home
screen instead of Settings
page.
For reference, this is my Home
page:
From there, I move to the Settings
page clicking the button on the top-right corner (title bar of the Home
page), which looks like:
If I click on the Login / Signup
button, we go to the third page Auth
, but the back button still shows Home Page
. It looks like this:
My app/_layout.tsx
looks like:
import { Stack, router } from "expo-router";
import { ThemeProvider, DefaultTheme, DarkTheme } from "@react-navigation/native";
import { StatusBar, useColorScheme } from "react-native";
import { SettingsButton } from "../src/components";
export default function HomePageLayout() {
const colorScheme = useColorScheme();
return (
<ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
<StatusBar barStyle="default" />
<Stack
screenOptions={{ headerShown: false, headerTintColor: "white", headerStyle: { backgroundColor: "black" }, headerTitleStyle: { fontWeight: "bold" } }}
>
<Stack.Screen
name="index"
options={{
title: "Home Page", headerShown: true, headerRight: () => (
<SettingsButton
color="white"
onPressFunction={() => router.push("settings")}
/>
),
}}
/>
<Stack.Screen
name="settings"
options={{ title: "Settings", headerShown: true }}
/>
<Stack.Screen
name="[missing]"
options={{ title: "Page Not Found", headerShown: true }}
/>
</Stack>
</ThemeProvider>
);
}
My app/index.tsx
looks like this:
import { Stack, router } from "expo-router";
import { View } from "react-native";
import { CustomButton, bodyStyles } from "../src/components/";
export default function App() {
return (
<>
<View style={[bodyStyles.container, { width: "100%" }]}>
<View style={bodyStyles.buttonContainer}>
<CustomButton
buttonTitle="Chat"
onPressFunction={() => console.log("Chat pressed")}
/>
</View>
</View>
</>
);
}
settings/_layout.tsx
:
import { Stack } from "expo-router";
export default function SettingsLayout() {
return (
<Stack>
<Stack.Screen name="index" options={{ headerShown: false }} />
<Stack.Screen name="auth" options={{ headerShown: false }} />
</Stack>
);
}
settings/index.tsx
:
import React from "react";
import { View } from "react-native";
import { router } from "expo-router";
import { bodyStyles, CustomButton } from "../../src/components";
export default function SettingsScreen() {
return (
<View style={[bodyStyles.container, bodyStyles.buttonContainer]}>
<CustomButton
buttonTitle="Login / Signup"
onPressFunction={() => router.push("/settings/auth")}
/>
</View>
);
}
settings/auth/_layout.tsx
:
import { Stack } from "expo-router";
export default function AuthLayout() {
return (
<Stack>
<Stack.Screen name="index" options={{ headerShown: false }} />
<Stack.Screen name="login" options={{ headerShown: false, presentation: "modal" }} />
<Stack.Screen name="signup" options={{ headerShown: false, presentation: "modal" }} />
</Stack>
);
}
settings/auth/index.tsx
:
import React from "react";
import { View, Text } from "react-native";
import { CustomButton, bodyStyles } from "../../../src/components";
import { router } from "expo-router";
export default function AuthScreen() {
return (
<View style={bodyStyles.container}>
<Text style={bodyStyles.header1}>Welcome user!!</Text>
<Text style={bodyStyles.header2}>Please login or create account!</Text>
<View style={bodyStyles.buttonContainer}>
<LoginButton />
<SignupButton />
<CustomButton
buttonTitle="Go Back"
onPressFunction={() => router.back()}
/>
</View>
</View>
);
}
I have given as much context as I think would be necessary. Please let me know what I am doing wrong. Also please feel free to let me know if I am not following any best practice that react-native should follow.
Thank you in advance!