我有一个
_layout.tsx
文件,如下所示:
const RootLayout = () => {
const router = useRouter();
const { user, isLoaded, isSignedIn } = useUser();
const { os } = usePlatform();
const { save } = useMeStore();
const { settings } = useSettingsStore();
const { me } = useMeStore();
const createUserOrFailMutation = useMutation(
api.api.user.findUserOrCreateOne
);
React.useEffect(() => {
if (isLoaded && !isSignedIn) {
router.replace("/login");
}
}, [isLoaded, isSignedIn]);
React.useEffect(() => {
if (!isSignedIn) {
save(null);
}
if (!!user) {
const me = {
firstName: user.firstName,
lastName: user.lastName,
id: user.id,
createdAt: user.createdAt,
updatedAt: user.updatedAt,
imageUrl: user.imageUrl,
lastLoginAt: user.lastSignInAt,
email: user.emailAddresses[0].emailAddress,
};
save(me);
} else {
save(null);
}
}, [user, isSignedIn]);
// Try to save a user to convex if not exists
React.useEffect(() => {
if (!!me) {
createUserOrFailMutation({
email: me.email,
firstName: me.firstName || "",
id: me.id,
image: me.imageUrl,
lastName: me.lastName || "",
});
}
}, [me]);
return (
<Stack>
<Stack.Screen
options={{
presentation: os === "ios" ? "modal" : "fullScreenModal",
headerTitle: "Sign In",
headerTitleStyle: {
fontFamily: FONTS.bold,
fontSize: 24,
color: COLORS.black,
},
headerLeft: ({}) => (
<TouchableOpacity
style={{
marginRight: 20,
}}
activeOpacity={0.7}
onPress={async () => {
if (settings.haptics) {
await onImpact();
}
router.replace("/");
}}
>
<Ionicons name="close-outline" size={30} color={COLORS.black} />
</TouchableOpacity>
),
headerStyle: { backgroundColor: COLORS.white },
headerTitleAlign: "center",
navigationBarHidden: true,
headerShadowVisible: false,
}}
name="(modals)/login"
/>
<Stack.Screen
options={{
presentation: os === "ios" ? "modal" : "fullScreenModal",
headerTitle: "Forgot Password",
headerTitleStyle: {
fontFamily: FONTS.bold,
fontSize: 24,
color: COLORS.black,
},
headerLeft: ({}) => (
<TouchableOpacity
style={{
marginRight: 20,
}}
activeOpacity={0.7}
onPress={async () => {
if (settings.haptics) {
await onImpact();
}
router.back();
}}
>
<Ionicons name="close-outline" size={30} color={COLORS.black} />
</TouchableOpacity>
),
headerStyle: { backgroundColor: COLORS.white },
headerTitleAlign: "center",
navigationBarHidden: true,
headerShadowVisible: false,
}}
name="(modals)/forgot_password"
/>
<Stack.Screen
options={{
presentation: os === "ios" ? "modal" : "fullScreenModal",
headerTitle: "Sign Up",
headerTitleStyle: {
fontFamily: FONTS.bold,
fontSize: 24,
color: COLORS.black,
},
headerLeft: ({}) => (
<TouchableOpacity
style={{
marginRight: 20,
flexDirection: "row",
gap: 10,
alignItems: "center",
}}
activeOpacity={0.7}
onPress={async () => {
if (settings.haptics) {
await onImpact();
}
router.back();
}}
>
<Ionicons name="chevron-back" size={30} color={COLORS.green} />
<Typography
variant="h5"
style={{
color: COLORS.green,
fontSize: 20,
}}
>
Sign In
</Typography>
</TouchableOpacity>
),
headerStyle: { backgroundColor: COLORS.white },
headerTitleAlign: "center",
navigationBarHidden: true,
headerShadowVisible: false,
}}
name="(modals)/register"
/>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen
name="profile"
options={{
headerShown: true,
title: "Profile",
headerTitleStyle: {
fontFamily: FONTS.bold,
fontSize: 24,
color: COLORS.black,
},
headerTitleAlign: "center",
navigationBarHidden: true,
headerShadowVisible: false,
headerBackVisible: false,
}}
/>
<Stack.Screen
name="verify"
options={{
headerShown: true,
title: "Verify Email",
headerTitleStyle: {
fontFamily: FONTS.bold,
fontSize: 24,
color: COLORS.black,
},
headerTitleAlign: "center",
navigationBarHidden: true,
headerShadowVisible: false,
headerBackVisible: false,
headerLeft: ({}) => (
<TouchableOpacity
style={{
marginRight: 20,
flexDirection: "row",
gap: 10,
alignItems: "center",
}}
activeOpacity={0.7}
onPress={async () => {
if (settings.haptics) {
await onImpact();
}
router.back();
}}
>
<Ionicons name="chevron-back" size={30} color={COLORS.green} />
<Typography
variant="h5"
style={{
color: COLORS.green,
fontSize: 20,
}}
>
Sign Up
</Typography>
</TouchableOpacity>
),
}}
/>
<Stack.Screen
name="reset_password"
options={{
headerShown: true,
title: "Update Password",
headerTitleStyle: {
fontFamily: FONTS.bold,
fontSize: 24,
color: COLORS.black,
},
headerTitleAlign: "center",
navigationBarHidden: true,
headerShadowVisible: false,
headerBackVisible: false,
headerLeft: ({}) => (
<TouchableOpacity
style={{
marginRight: 20,
flexDirection: "row",
gap: 10,
alignItems: "center",
}}
activeOpacity={0.7}
onPress={async () => {
if (settings.haptics) {
await onImpact();
}
router.back();
}}
>
<Ionicons name="chevron-back" size={30} color={COLORS.green} />
<Typography
variant="h5"
style={{
color: COLORS.green,
fontSize: 20,
}}
>
Forgot Pwd
</Typography>
</TouchableOpacity>
),
}}
/>
<Stack.Screen name="+not-found" />
</Stack>
);
};
当我尝试从
register
模式屏幕导航到 profile
屏幕时,它在 ios
上失败。我正在使用 useRouter
钩子,如下所示:
....
const router = useRouter();
<Button
title="Hello"
onPress={() =>
router.navigate({
pathname: "/profile",
params: {
email_address: state.email,
},
})
}
/>
它在
ios
上不起作用,但在 Android 上它确实有效。
"expo": "~51.0.21"
"expo-router": "~3.5.18"
ios
有什么问题吗?
我设法解决了这个问题。它实际上是在导航,但是模式始终位于我的个人资料屏幕顶部,我通过在导航后弹出模式来解决这个问题
import { StackActions } from "@react-navigation/native";
import { useNavigation, useRouter } from "expo-router";
const router = useRouter();
const navigation = useNavigation();
....
<Button
title="Hello"
onPress={() =>{
navigation.dispatch(StackActions.pop());
router.navigate({
pathname: "/profile",
params: {
email_address: state.email,
},
})
}
}
/>