【问题标题】:React Native Navigation : Navigate to another Stack Navigation (Nested)React Native Navigation:导航到另一个堆栈导航(嵌套)
【发布时间】:2021-09-02 16:27:07
【问题描述】:

几个小时以来,我一直在尝试从 StackNavigation 导航到另一个 Stack 导航。
我正在使用打字稿,这并不容易为所有屏幕定义正确的类型。

我用下面的例子来说明我的错误。
在这种情况下,当我的应用程序启动时,第一个屏幕是ProfilHome
在这个屏幕上我有两个按钮:

  • 一个去我当前stackNavigation的另一个屏幕ProfilInfo
  • 另一个去另一个堆栈导航MarketStack和屏幕MarketInfo

当我点击第一个按钮时,没有问题。但是当我点击第二个按钮时,我得到了错误:

The action 'NAVIGATE' with payload {"name":"MarketInfo"} was not handled by any navigator.
Do you have a screen named 'MarketInfo'?

错误代码:

import * as React from 'react'
import {View, Text, Button} from 'react-native'
import { ReactElement } from 'react'
import {createStackNavigator, StackNavigationProp, StackScreenProps} from '@react-navigation/stack'
import {useNavigation} from "@react-navigation/native";

//**********************//
// Profile component
//**********************//
type ProfileNavigationStack = {
    ProfilHome: undefined,
    ProfilInfo: undefined,
}
type ProfileHomeNavProps = StackScreenProps<ProfileNavigationStack, 'ProfilHome'>

const ProfileStack = createStackNavigator<ProfileNavigationStack>()
const ProfileComponent = () => {
    return (
        <ProfileStack.Navigator>
            <ProfileStack.Screen
                options={{ headerTitle: 'ProfilHome' }}
                name="ProfilHome"
                component={ProfileHome}
            />
            <ProfileStack.Screen
                options={{ headerTitle: 'ProfilInfo' }}
                name="ProfilInfo"
                component={ProfileInfo}
            />
        </ProfileStack.Navigator>
    )
}

const ProfileHome = ({ navigation }: ProfileHomeNavProps) => {
    const navToMarket = useNavigation<MarketHomeNavProps>()

    return (
        <View>
            <Text>ProfileHome</Text>
            <Button title={'goToInfo'} onPress={() => navigation.navigate('ProfilInfo')}/>
            <Button title={'goToMarket'} onPress={() => navToMarket.navigate('MarketInfo')}/>
        </View>
    )
}
const ProfileInfo = () => (<View><Text>ProfileInfo</Text></View>)

//**********************//
// Market component
//**********************//
type MarketNavigationStack = {
    MarketHome: undefined,
    MarketInfo: undefined,
}
type MarketHomeNavProps = StackNavigationProp<MarketNavigationStack, 'MarketHome'>

const MarketStack = createStackNavigator<MarketNavigationStack>()
const MarketComponent = () => {
    return (
        <MarketStack.Navigator>
            <MarketStack.Screen
                options={{ headerTitle: 'ProfilHome' }}
                name="MarketHome"
                component={MarketHome}
            />
            <MarketStack.Screen
                options={{ headerTitle: 'MarketInfo' }}
                name="MarketInfo"
                component={MarketInfo}
            />
        </MarketStack.Navigator>
    )
}

const MarketHome = () => (<View><Text>MarketHome</Text></View>)
const MarketInfo = () => (<View><Text>MarketHome</Text></View>)


//**********************//
// Main component
//**********************//
type HomeNavigationStack = {
    Profile: undefined,
    Market: undefined,
}
const HomeStack = createStackNavigator<HomeNavigationStack>()

export default function StartApp(): ReactElement {
    return (
        <HomeStack.Navigator
            screenOptions={{
                headerShown: false,
            }}
        >
            <HomeStack.Screen
                name="Profile"
                component={ProfileComponent}
            />
            <HomeStack.Screen
                name="Market"
                component={MarketComponent}
            />
        </HomeStack.Navigator>
    )
}

我认为解决方案是here,但我不明白它是如何工作的。

有人可以帮我吗?

谢谢

【问题讨论】:

    标签: typescript react-native react-navigation typescript-typings react-native-navigation


    【解决方案1】:

    首先,如果您的组件被传递到堆栈或任何其他可以直接传递导航道具的导航器容器,您实际上不需要像这里那样使用useNavigation钩子,如果您无法访问@ 987654324@直接支持,useNavigation docs.

    const ProfileHome = ({ navigation }: ProfileHomeNavProps) => {
        const navToMarket = useNavigation<MarketHomeNavProps>()/// <-- that isn't needed, you can directly use navigation prop
    
        return (
            <View>
                <Text>ProfileHome</Text>
                <Button title={'goToInfo'} onPress={() => navigation.navigate('ProfilInfo')}/>
                <Button title={'goToMarket'} onPress={() => navToMarket.navigate('MarketInfo')}/> ///<-- so instead of using navToMarket you can just use navigation as you have used it in navigating to 'ProfilInfo'
            </View>
        )
    }
    

    然后,要导航到嵌套在另一个堆栈中的屏幕,您可以传递一个堆栈名称和带有 screen 属性的对象,这将是您在该堆栈中的屏幕名称。 由于您的“嵌套”堆栈名称在您的根 (HomeStack) 组件中为“Market”,而在您的“Market”堆栈中,所需的屏幕名称为“MarketInfo”,您应该使用如下导航功能:

    navigation.navigate('Market', { screen: 'MarketInfo' })
    

    您可以在docs 中阅读有关嵌套导航器/导航到嵌套屏幕的更多信息。

    【讨论】:

    • 使用嵌套解决方案时,它可以正常工作,但我遇到了打字稿错误:Argument of type '["Market", { screen: string; }]' is not assignable to parameter of type '["ProfilHome" | "ProfilInfo"] | ["ProfilHome" | "ProfilInfo", undefined]'
    • 您需要将MarketInfo路由添加到您的ProfileNavigationStack,您需要定义所有可以从堆栈导航的路由,在相应的类型声明中,您可以将Market: { screen: string }放入该类型并错误应该消失了。
    猜你喜欢
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2022-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多