I am new to react native, and i'm using new react-navigation v.5 in my react-native app. When i use createStackNavigator and createBottomTabNavigator together in NavigationContainer i have errors - "undefined is not an object" and "Another navigator is already registered for this container. You likely have multiple navigators under a single "NavigationContainer" or "Screen". Make sure each navigator is under a separate "Screen" container." (in React Navigation v.5). Please tell me where i`m wrong?
AppNavigation.tsx
import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import { MainScreen } from "../screens/MainScreen";
import { PostScreen } from "../screens/PostScreen";
import { AboutScreen } from "../screens/AboutScreen";
import { BookedScreen } from "../screens/BookedScreen";
import { CreateScreen } from "../screens/CreateScreen";
import { THEME } from "../theme";
import { Platform } from "react-native";
import { AppHeaderIcon } from "../components/AppHeaderIcon";
import { HeaderButtons, Item } from "react-navigation-header-buttons";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
type RootStackParamList = {
Main: undefined;
Post: { postId?: string; date?: string; booked?: boolean };
About: undefined;
Booked: undefined;
Create: undefined;
};
const headerButtons = (title: string, icon: string, callback: () => void) => {
return (
<HeaderButtons HeaderButtonComponent={AppHeaderIcon}>
<Item title={title} iconName={icon} onPress={() => callback()} />
</HeaderButtons>
);
};
export const AppNavigation = () => {
const Stack = createStackNavigator<RootStackParamList>();
const Tab = createBottomTabNavigator();
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Main"
screenOptions={{
headerTintColor:
Platform.OS === "android" ? "white" : THEME.MAIN_COLOR,
headerStyle: {
backgroundColor:
Platform.OS === "android" ? THEME.MAIN_COLOR : "white"
}
}}
>
<Stack.Screen
name="Main"
component={MainScreen}
options={{
headerTitle: "Мой блог",
headerRight: () =>
headerButtons("Сделать фото", "ios-camera", () =>
console.log("Press camera")
),
headerLeft: () =>
headerButtons("drower", "ios-menu", () =>
console.log("Press drower button")
)
}}
/>
<Stack.Screen
name="Post"
component={PostScreen}
options={({ route }) => ({
headerTitle: `Пост от ${new Date(
route.params.date
).toLocaleDateString()}`,
headerRight: () =>
headerButtons(
"star",
route.params.booked ? "ios-star" : "ios-star-outline",
() => console.log("Press star button")
)
})}
/>
<Stack.Screen name="About" component={AboutScreen} />
<Stack.Screen name="Booked" component={BookedScreen} />
<Stack.Screen name="Create" component={CreateScreen} />
</Stack.Navigator>
<Tab.Navigator>
<Tab.Screen name="Post" component={PostScreen} />
<Tab.Screen name="Booked" component={BookedScreen} />
</Tab.Navigator>
</NavigationContainer>
);
};
App.tsx
import React, { useState } from "react";
import { AppLoading } from "expo";
import { bootstrap } from "./src/bootstrap";
import { AppNavigation } from "./src/navigation/AppNavigation";
export default function App() {
const [isReady, setIsReady] = useState(false);
if (!isReady) {
//AppLoading - пока не завершится выполнение код дальше не пойдет
return (
<AppLoading
startAsync={bootstrap}
onFinish={() => setIsReady(true)}
onError={err => console.log('AppLoading error - ', err)}
/>
);
}
return <AppNavigation />;
}