4

I have been trying to nest multiple navigators in React Native without success.

What I want is a BottomTabsNavigator with:

  • Home
  • Psalmen: regular page is grid with 150 items and when clicked goes to details psalmen/:psalm
    • Vers: click on a vers within a psalm and then you have a MaterialTopBarNavigator with all the verses from that psalm psalmen/:psalm/:vers
  • Settings

EDIT For clarification: Im having trouble understandig how to set up these nested navigators with the correct types. I cam as far as getting one nested navigator to work but not more than that.

What I have now:

const BottomTabsNavigator: React.FC = () => {
    return (
        <BottomTabs.Navigator>
            <BottomTabs.Screen name="Home" component={HomeScreen} />
            <BottomTabs.Screen name="Psalmen" component={PsalmenStackNavigator} />
            <BottomTabs.Screen name="Settings" component={SettingsScreen} />
        </BottomTabs.Navigator>
    );
};
const PsalmenStackNavigator: React.FC<PsalmenScreenProps> = () => {
    const theme = useTheme();

    return (
        <PsalmenStack.Navigator
            screenOptions={{
                headerTitleStyle: { color: theme.colors.text },
                headerTintColor: Platform.OS === "ios" ? theme.colors.tertiary : theme.colors.text,
            }}
        >
            <PsalmenStack.Screen name="Psalmen" component={PsalmenScreen} />
            <PsalmenStack.Screen name="Psalm" component={PsalmStackNavigator} />
        </PsalmenStack.Navigator>
    );
};
const PsalmStackNavigator: React.FC = () => {
    return (
        <PsalmStack.Navigator>
            <PsalmStack.Screen name="Vers" component={VersStackNavigator} />
            <PsalmStack.Screen
                name="Psalm"
                component={PsalmScreen}
                options={({ route }) => ({
                    headerTitle: `Psalm ${route.params.psalm}`,
                    headerRight: () => <ToggleNotes />,
                })}
            />
        </PsalmStack.Navigator>
    );
};
const VersStackNavigator: React.FC<VersStackScreenProps> = ({ route }) => {
    const { psalm, vers: nummer } = route.params;
    const psalmen = data as unknown as Record<string, IPsalm>;
    const psalmData = psalmen[psalm.toString()];
    const { verzen } = psalmData;

    return (
        <VersStack.Navigator>
            {verzen.map(vers => (
                <VersStack.Screen
                    name={vers.nummer.toString()}
                    key={`${psalm}-${vers.nummer}`}
                    component={VersScreen}
                    options={option => ({
                        headerTitle: `Psalm  ${option.route.params.psalm}:${option.route.params.vers}`,
                        headerRight: () => <ToggleNotes />,
                    })}
                />
            ))}
        </VersStack.Navigator>
    );
};

I think my problem is in the last 2 codeblocks but I am not sure and could require some help. I'm also writing this in Typescript so I am having problems with the types aswell.


export type VersStackScreenProps = CompositeScreenProps<
    NativeStackScreenProps<VersStackList, "Vers">,
    PsalmScreenProps
>;

export type PsalmScreenProps = CompositeScreenProps<
    NativeStackScreenProps<PsalmStackList, "Psalm">,
    PsalmenScreenProps
>;

export type PsalmenScreenProps = CompositeScreenProps<
    NativeStackScreenProps<PsalmenStackList, "Psalmen">,
    BottomTabScreenProps<BottomTabsList>
>;

export type TabStackScreenProps<T extends keyof BottomTabsList> = BottomTabScreenProps<
    BottomTabsList,
    T
>;

export type BottomTabsList = {
    Home: undefined;
    Psalmen: NavigatorScreenParams<PsalmenStackList> | undefined;
    Settings: undefined;
};

export type PsalmenStackList = {
    Psalmen: undefined;
    Psalm: NavigatorScreenParams<PsalmStackList> | undefined;
};

export type PsalmStackList = {
    Psalm: { psalm: number };
    Vers: { vers: number; psalm: number };
};

export type VersStackList = Record<string, { vers: number; psalm: number }>;
Joël
  • 51
  • 3

0 Answers0