简体   繁体   English

如何在 React native 的父导航中导航到屏幕

[英]How to navigate to a screen in parent navigation in React native

I am very new to React Navigation and am trying to implement the following functionality in react-native: I have a stack navigator as a parent and a bottom navigation bar as its child.我是 React Navigation 的新手,正在尝试在 react-native 中实现以下功能:我有一个堆栈导航器作为父级,底部导航栏作为其子级。 From the home screen, when the user clicks the logout option, they should return to the Sign In screen which is a part of the parent navigation.在主屏幕上,当用户单击注销选项时,他们应该返回到作为父导航一部分的登录屏幕。

There are already a lot of questions regarding this, but I am not able to implement the previous solutions in my code.已经有很多关于此的问题,但我无法在我的代码中实现以前的解决方案。

Someone please help me out, the code is given below (This is an Expo managed project):有人请帮助我,代码如下(这是一个 Expo 管理的项目):

Navigation Components导航组件

import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import WelcomeScreen from "../screens/WelcomeScreen";
import Features from "../screens/Features";
import SignIn from "../screens/SignIn";
import Register from "../screens/Register";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { Icon } from "react-native-elements";
import Home from "../screens/Home";
import Reminders from "../screens/Reminders";
import Settings from "../screens/Settings";

const BottomNavbar = () => {
    const Tab = createBottomTabNavigator();
    return (
        <Tab.Navigator
            initialRouteName="Home"
            screenOptions={({ route }) => ({
                tabBarIcon: ({ focused }) => {
                    let iconName;
                    let rn = route.name;
                    if (rn === "Home") {
                        iconName = focused ? "home" : "home-outline";
                    } else if (rn === "Reminders") {
                        iconName = focused ? "list" : "list-outline";
                    } else if (rn === "Settings") {
                        iconName = focused ? "settings" : "settings-outline";
                    }
                    return (
                        <Icon
                            name={iconName}
                            size={25}
                            color="black"
                            type="ionicon"
                        />
                    );
                },
            })}
            showLabel
        >
            <Tab.Screen
                name="Home"
                component={Home}
                options={{ headerShown: false }}
            />
            <Tab.Screen
                name="Reminders"
                component={Reminders}
                options={{ headerShown: false }}
            />
            <Tab.Screen
                name="Settings"
                component={Settings}
                options={{ headerShown: false }}
            />
        </Tab.Navigator>
    );
};

const Navigator = () => {
    const Stack = createNativeStackNavigator();

    return (
        <NavigationContainer>
            <Stack.Navigator
                screenOptions={{ headerShown: false }}
                initialRouteName="Welcome"
            >
                <Stack.Screen name="Welcome" component={WelcomeScreen} />
                <Stack.Screen name="Features" component={Features} />
                <Stack.Screen name="SignIn" component={SignIn} />
                <Stack.Screen name="Register" component={Register} />
                <Stack.Screen name="BottomNavbar" component={BottomNavbar} />
            </Stack.Navigator>
        </NavigationContainer>
    );
};

export default Navigator;

Home Screen Components主屏幕组件

import {
    View,
    Text,
    SafeAreaView,
    StyleSheet,
    TouchableOpacity,
    ScrollView,
} from "react-native";
import React from "react";
import { Header, Image, Icon } from "react-native-elements";
import { useFonts } from "expo-font";
import ServiceCard from "../components/ServiceCard";
import PetCard from "../components/PetCard";

const SignOut = ({ navigation }) => {
    return (
        <TouchableOpacity
            onPress={() => {
                navigation.navigate("SignIn");
            }}
        >
            <Icon name="logout" color="black" size={20} />
        </TouchableOpacity>
    );
};

const Home = () => {
    const [loaded, error] = useFonts({
        Montserrat: require("../assets/fonts/Montserrat-Regular.ttf"),
    });
    if (!loaded) {
        return null;
    }
    const url1 =
        "https://images.unsplash.com/photo-1530281700549-e82e7bf110d6?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=388&q=80";
    const url2 =
        "https://images.unsplash.com/photo-1560807707-8cc77767d783?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=435&q=80";
    const url3 =
        "https://images.unsplash.com/photo-1543466835-00a7907e9de1?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80";
    return (
        <View style={styles.screen}>
            <Header
                leftComponent={{
                    icon: "menu",
                    color: "black",
                }}
                rightComponent={<SignOut />}
                centerComponent={{
                    text: "PetPapa",
                    color: "black",
                    style: {
                        fontFamily: "Montserrat",
                        fontSize: 20,
                    },
                }}
                barStyle="dark-content"
                backgroundColor="white"
                containerStyle={styles.header}
            />
            <View style={styles.community}>
                <View style={styles.commOffer}>
                    <View>
                        <Text style={styles.commOfferTitle}>Join our</Text>
                        <Text style={styles.commOfferTitle}>
                            community today!
                        </Text>
                    </View>
                    <TouchableOpacity style={styles.btn}>
                        <Text style={styles.commOfferJoin}>Join Now</Text>
                    </TouchableOpacity>
                </View>
                <Image
                    source={{
                        uri: "https://imgur.com/nB4Xm1Z.png",
                    }}
                    style={styles.commDog}
                />
            </View>
            <View style={styles.listView}>
                <View style={styles.topText}>
                    <Text style={styles.title}>Services</Text>
                    <TouchableOpacity>
                        <Text style={styles.option}>See more</Text>
                    </TouchableOpacity>
                </View>
                <ServiceCard />
            </View>
            <View style={styles.listView}>
                <View style={styles.topText}>
                    <Text style={styles.title}>My Pets</Text>
                    <TouchableOpacity>
                        <Text style={styles.option}>See all</Text>
                    </TouchableOpacity>
                </View>
                <ScrollView
                    style={styles.petView}
                    horizontal={true}
                    showsHorizontalScrollIndicator={true}
                    persistentScrollbar={true}
                >
                    <PetCard name="Miles" Img={url1} />
                    <PetCard name="Jack" Img={url2} />
                    <PetCard name="Ellie" Img={url3} />
                </ScrollView>
            </View>
        </View>
    );
};

const styles = StyleSheet.create({
    screen: {
        height: "100%",
        backgroundColor: "white",
        alignItems: "center",
    },
    header: {
        backgroundColor: "white",
        height: 80,
    },
    community: {
        backgroundColor: "#1976D2",
        height: "15%",
        width: "80%",
        borderRadius: 20,
        marginTop: 50,
        flexDirection: "row",
        justifyContent: "space-around",
    },
    commDog: {
        marginTop: 10,
        marginRight: 15,
        height: 105,
        width: 75,
    },
    commOffer: {
        marginTop: 10,
        flexDirection: "column",
        justifyContent: "space-around",
    },
    commOfferTitle: {
        color: "white",
        fontFamily: "Montserrat",
        fontSize: 16,
    },
    btn: {
        backgroundColor: "#FFC107",
        width: "50%",
        borderRadius: 10,
    },
    commOfferJoin: {
        color: "white",
        margin: 5,
    },
    listView: {
        marginTop: 50,
        width: "80%",
    },
    topText: {
        flexDirection: "row",
        justifyContent: "space-between",
        alignItems: "center",
    },
    title: {
        fontFamily: "Montserrat",
        fontWeight: "600",
    },
    option: {
        fontFamily: "Montserrat",
        opacity: 0.4,
    },
    block: {
        backgroundColor: "#FF5677",
        width: 75,
        height: 100,
        justifyContent: "center",
        alignItems: "center",
        marginTop: 25,
        borderRadius: 20,
    },
    petView: {
        width: "100%",
        backgroundColor: "white",
        height: 250,
    },
});
export default Home;

My Directory Structure:我的目录结构:

项目的目录结构

First you need to add navigation prop to Home screen component首先,您需要将导航道具添加到主屏幕组件

const Home = ({navigation}) => {
    const [loaded, error] = useFonts({
        Montserrat: require("../assets/fonts/Montserrat-Regular.ttf"),
    });
   ...

then You need to pass navigation prop to the signout component然后您需要将导航道具传递给注销组件

 <Header
    leftComponent={{
       icon: "menu",
       color: "black",
    }}
    rightComponent={<SignOut navigation={navigation} />}
    ...

You can also use useNavigation hook from react navigation您还可以使用反应导航中的 useNavigation 挂钩

import { useNavigation } from '@react-navigation/native';

const SignOut = ({}) => {
    const navigation = useNavigation()
    return (
        <TouchableOpacity
            onPress={() => {
                navigation.navigate("SignIn");
            }}
        >
            <Icon name="logout" color="black" size={20} />
        </TouchableOpacity>
    );
};

If You want to create login flow then you should use Authentication flow which I think best prectice and recommended way如果您想创建登录流程,那么您应该使用身份验证流程,我认为这是最佳实践和推荐方式

The problem in current flow if you logout and navigate to sign-in page once then if you navigate back from you app then as behaviour of stack navigation it just pop current screen and it will again navigate to home screen which is not what supposed to be correct.当前流程中的问题如果您注销并导航到登录页面一次然后如果您从您的应用程序导航回来然后作为堆栈导航的行为它只会弹出当前屏幕并且它将再次导航到主屏幕这不是应该的正确的。

You can learn it from react-navigation offical doc https://reactnavigation.org/docs/auth-flow/可以从 react-navigation 官方文档https://reactnavigation.org/docs/auth-flow/ 了解

if you want a video tutorial how to implement Authentication flow using redux(state management lib) then I have video tutorial you can learn this video -> https://youtu.be/cm1oJ7JmW6c如果你想要一个视频教程如何使用 redux(状态管理库)实现身份验证流程那么我有视频教程你可以学习这个视频 -> https://youtu.be/cm1oJ7JmW6c

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 react-native-navigation 导航到另一个屏幕 - Navigate to another screen with react-native-navigation 如何使用反应导航导航到反应原生的新屏幕并且组件位于不同的文件中 - How to navigate to a new screen in react native using react navigation and the components are in a different file 在React Native中如何在重置导航堆栈的同时从子Stack Navigator导航回父项 - How to navigate from a child Stack Navigator back to parent while resetting navigation stack at the same time, in React Native 如何使用 navigation.navigate -react native 在深度嵌套的导航器中设置特定屏幕 - How to set a specific screen in deeply nested navigator with navigation.navigate -react native React Native Navigation,按下警报按钮后如何导航到另一个屏幕? - React Native Navigation, How do I navigate to another screen after pressing the button of an alert? 如何导航到 react-native 中的嵌套屏幕 - How to navigate to nested screen in react-native 如何在 React Native 上的屏幕之间导航? - How to navigate between screen on React Native? React Native:如何将屏幕更改/导航为子组件? - React Native: How to change/navigate the Screen as a Childcomponent? React Navigation-自定义屏幕导航 - React Navigation - custom screen navigate 在屏幕 React Native 之间导航 - Navigate Between Screen React Native
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM