How to Create BottomNavigator in React Native? - react-native

I'd like to create a BottomNavigator in React Native. But I have this error :Creating a navigator doesn't take an argument. Maybe you are trying to use React Navigation 4 API with React Navigation 5?". I tried many times for searching a solution, but I always have this error. I know that I used deprecated syntax but I can't find how to do it... Thanks for your help guys.
import React from 'react'
import { createAppContainer } from 'react-navigation'
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createStackNavigator } from 'react-navigation-stack'
import Search from '../Components/Search'
import FilmDetail from '../Components/FilmDetail'
import Favorites from '../Components/Favorites'
const SearchStackNavigator = createStackNavigator({
Search: {
screen: Search,
navigationOptions: {
title: 'Rechercher'
}
},
FilmDetail: {
screen: FilmDetail
}
})
const MoviesTabNavigator = createBottomTabNavigator(
{
Search: {
screen: SearchStackNavigator,
navigationOptions: {
tabBarIcon: () => {
return <Image
source={require('../Images/ic_search.png')}
style={styles.icon}/>
}
}
},
Favorites: {
screen: Favorites,
navigationOptions: {
tabBarIcon: () => {
return <Image
source={require('../Images/ic_favorite.png')}
style={styles.icon}/>
}
}
}
},
{
tabBarOptions: {
activeBackgroundColor: '#DDDDDD',
inactiveBackgroundColor: '#FFFFFF',
showLabel: false,
showIcon: true
}
}
)
const styles = StyleSheet.create({
icon: {
width: 30,
height: 30
}
})
export default createAppContainer(MoviesTabNavigator)

Related

error adding a splash to my expo react native app

I have my next splash, my idea is to be able to show my app logo when opening the application and then go to the start of the application, it works fine:
import React from 'react';
import { StyleSheet, Image, View, Text } from 'react-native';
import { StackActions, NavigationActions } from 'react-navigation';
export default class Splash extends React.Component {
goToScreen(routeName){
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: routeName })],
});
this.props.navigation.dispatch(resetAction);
}
/*goToScreen(routeName){
this.props.navigation.navigate(routeName)
}*/
componentDidMount(){
setTimeout( () => {
this.goToScreen('Home')
}, 2000, this)
}
render(){
return (
<View style={styles.container}>
<Image source={{uri: 'https://i.imgur.com/r0jUwOD.png'}} style={{width: 250, height: 250}} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#33B747',
alignItems: 'center',
justifyContent: 'center'
},
});
The problem is the location of the splash, since in this way if it shows me, but it creates a lower button called Splash, on the other hand the splash when loading is shown in conjunction with the lower buttons and that should not happen, the splash must display only in full screen and not create a button.
AppNavigator.js
import React from 'react';
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import { createAppContainer } from 'react-navigation';
import { MaterialIcons, MaterialCommunityIcons } from '#expo/vector-icons';
import Splash from '../screens/Splash';
import NewsListScreen from '../screens/NewsListScreen';
import NewsItemScreen from '../screens/NewsItemScreen';
const StackNavigator = createStackNavigator({
Splash: {
screen: Splash,
navigationOptions: {
headerShown: false,
}
},
News: {
screen: NewsListScreen
},
Root: {
screen: BottomTabNavigator,
},
NewsItem: {
screen: NewsItemScreen,
navigationOptions: {
headerTitle: 'News Item'
}
},
},{
initialRouteName: 'Splash'
});
const BottomTabNavigator = createBottomTabNavigator({
Home: {
screen: StackNavigator,
navigationOptions: {
tabBarIcon: () => <MaterialIcons name="home" size={24} />
}
},
News: {
screen: StackNavigator,
navigationOptions: {
tabBarIcon: () => <MaterialCommunityIcons name="newspaper-variant-outline" size={24} />
}
}
})
export default createAppContainer(BottomTabNavigator);
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { AppLoading } from 'expo';
import { Provider } from 'react-redux';
import AppNavigator from './app/resources/navigation/AppNavigator';
import ReduxStore from './app/resources/redux/ReduxStore';
export default function App() {
return (
<Provider store={ReduxStore}>
<AppNavigator />
</Provider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Attached capture of the error upload in imgur capture 1 and capture 2
The recommended way to add a splash screen to an expo managed app can be found here.
I've managed to create an expo project and achieve the exact same behavior that you've looking for.
I've used react-navigation 4.x.x
This is how it looks and you can find the full code here
Here is the code I've used.
Splash.js
import React, { Component } from "react";
import { Text, SafeAreaView, View, StyleSheet } from "react-native";
import { StackActions, NavigationActions } from "react-navigation";
export class Splash extends Component {
goToScreen(routeName) {
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: routeName })],
});
this.props.navigation.dispatch(resetAction);
}
componentDidMount() {
setTimeout(
() => {
this.goToScreen("Root");
},
2000,
this
);
}
render() {
return (
<SafeAreaView style={styles.mainContainer}>
<Text style={styles.text}> Splash Screen </Text>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
mainContainer: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#efef21",
},
text: {
fontSize: 22,
},
});
export default Splash;
Navigator.js
import { createStackNavigator } from "react-navigation-stack";
import { createAppContainer } from "react-navigation";
import Home from "./Home";
import Splash from "./Splash";
import TabNavigator from "./BottomTabNavigator";
const AppNavigator = createStackNavigator(
{
Splash: {
screen: Splash,
navigationOptions: {
headerShown: false,
},
},
Root: {
screen: TabNavigator,
navigationOptions: {
headerShown: false,
},
},
},
{
initialRouteName: "Splash",
}
);
export default createAppContainer(AppNavigator);
BottomTabNavigator.js
import { createAppContainer } from "react-navigation";
import { createBottomTabNavigator } from "react-navigation-tabs";
import Home from "./Home";
import News from "./News";
const TabNavigator = createBottomTabNavigator({
Home: {
screen: Home,
navigationOptions: {
title: "Home",
},
},
News: {
screen: News,
navigationOptions: {
title: "News",
},
},
});
export default createAppContainer(TabNavigator);
Also, I've achieved the same behavior using react-navigation 5.x.x
You can find my code here
Edit 01
If you want to have the headers, You need to use a Stack Navigator for each tab.
Here is the updated code of BottomTabNAvigator.js
import { createAppContainer } from "react-navigation";
import { createBottomTabNavigator } from "react-navigation-tabs";
import { createStackNavigator } from "react-navigation-stack";
import Home from "./Home";
import News from "./News";
const HomeStack = createStackNavigator({
Home: Home,
});
const NewsStack = createStackNavigator({
News: News,
});
const TabNavigator = createBottomTabNavigator({
Home: {
screen: HomeStack,
navigationOptions: {
headerTitle: "Home",
title: "Home",
},
},
News: {
screen: NewsStack,
navigationOptions: {
title: "News",
},
},
});
export default createAppContainer(TabNavigator);
You have used Splash: {screen: Splash}, in your BottomTabNavigator so obviously it will add splash as on bottom navigator.
Remove Splash: {screen: Splash}, from BottomTabNavigator and paste it on StackNavigator and set splash as initialRouteName
const StackNavigator = createStackNavigator({
News: {
screen: NewsListScreen
},
Splash: {screen: Splash},
NewsItem: {
screen: NewsItemScreen,
navigationOptions: {
headerTitle: 'News Item'
}
},
},
{
initialRouteName : 'Splash'
});
you have to move splash screen to StackNavigator and add BottomTabNavigator into StackNavigator as a screen like this
import React from 'react';
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from 'react-navigation-tabs';
import { createAppContainer } from 'react-navigation';
import { MaterialIcons } from '#expo/vector-icons';
import Splash from '../screens/Splash';
import NewsListScreen from '../screens/NewsListScreen';
import NewsItemScreen from '../screens/NewsItemScreen';
const StackNavigator = createStackNavigator({
Splash: {
screen: Splash
},
Home: {
screen: BottomTabNavigator
},
News: {
screen: NewsListScreen
},
NewsItem: {
screen: NewsItemScreen,
navigationOptions: {
headerTitle: 'News Item'
}
}
},
{
initialRouteName: "Splash",
});
const BottomTabNavigator = createBottomTabNavigator({
Home: {
screen: StackNavigator,
navigationOptions: {
tabBarIcon: () => <MaterialIcons name="home" size={24} />
}
}
})
export default createAppContainer(StackNavigator);

How to use setState or useState with react native bottom tab navigation v4

First of all I want to say sorry because of my bad English here...
I want to use setState or use State hooks in Route.js file I don't know how to do it. If anyone knows the answer - please help me..
I have used asyncstorage but it is not make effect automatically when data has been updated.. it wants refresh or save Route.js file at every moment.
This is my Route.js file
import React from 'react';
import { Button, Image } from 'react-native';
import {createAppContainer} from 'react-navigation';
import {createBottomTabNavigator} from 'react-navigation-tabs';
import {createStackNavigator} from 'react-navigation-stack';
import HomeScreen from './pages/HomeScreen';
import SettingsScreen from './pages/SettingsScreen';
import DetailsScreen from './pages/DetailsScreen';
import ProfileScreen from './pages/ProfileScreen';
const HomeStack = createStackNavigator(
{
Home: { screen: HomeScreen },
Details: { screen: DetailsScreen },
},
{
defaultNavigationOptions: {
headerStyle: {
backgroundColor: '#42f44b',
},
headerTintColor: '#FFFFFF',
title: 'Home',
},
}
);
const SettingsStack = createStackNavigator(
{
Settings: { screen: SettingsScreen },
Details: { screen: DetailsScreen },
}, // here i have use asycstroage but it is not working properly
{
defaultNavigationOptions: {
headerStyle: {
backgroundColor: '#42f44b',
},
headerTintColor: '#FFFFFF',
title: 'Settings',
},
}
);
const App = createBottomTabNavigator(
{
Home: { screen: HomeStack },
Settings: { screen: SettingsStack },
},
{
defaultNavigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, horizontal, tintColor }) => {
const { routeName } = navigation.state;
if (routeName === 'Home') {
return ( <Image source={ focused ? require('./asset/home.png') :
require('./asset/bar.png')}
style={{ width: 20,
height: 20,
borderRadius: 40 / 2,
}} />
);
} else if (routeName === 'Settings') {
return ( <Image source={ focused ? require('./asset/setting.png') :
require('./asset/bar.png')}
style={{ width: 20,
height: 20,
borderRadius: 40 / 2,
}} />
);
}
},
}),
}
);
export default createAppContainer(App);
So how can I do it?
And how to pass this state with navigation screen..
Thanks..

createBottomTabNavigator does not renders createStackNavigator when clicked

I am following the react-navigation tutorial and everything was working fine until I tried using createBottomTabNavigator , I am passing two createStackNavigator to createBottomTabNavigator, the first screen showing meals categories is rendered without any issue but when I press Favorite Tab(the one with star icon) then I am greeted with the blank screen, FavNavigator is not getting rendered at all.
I tried replacing FavNavigator with FavoritesScreen component and it's being shown but the header bar is missing.
Here is app:
Here is the navigator configuration code:
import React from "react";
import { createStackNavigator } from "react-navigation-stack";
import { createBottomTabNavigator } from "react-navigation-tabs";
import { createAppContainer } from "react-navigation";
import { Ionicons } from "#expo/vector-icons";
import { createMaterialBottomTabNavigator } from "react-navigation-material-bottom-tabs";
import CategoriesScreen from "../screens/CategoriesScreen";
import CategoryMealsScreen from "../screens/CategoryMealsScreen";
import MealsDetailScreen from "../screens/MealsDetailScreen";
import FavoritesScreen from "../screens/FavoritesScreen";
import Colors from "../constans/Colors";
import { Platform } from "react-native";
const defaultStackNavOptions = {
headerStyle: {
backgroundColor: Platform.OS === "android" ? Colors.primaryColor : ""
},
headerTintColor: Platform.OS === "android" ? "white" : Colors.primaryColor,
headerTitle: "A Screen"
};
const MealsNavigator = createStackNavigator(
{
Categories: {
screen: CategoriesScreen
},
CategoryMeals: {
screen: CategoryMealsScreen
},
MealDetail: MealsDetailScreen
},
{
defaultNavigationOptions: defaultStackNavOptions
}
);
const FavNavigator = createStackNavigator(
{
Favorites: FavoritesScreen,
MealDetail: MealsDetailScreen
},
{
defaultNavigationOptions: defaultStackNavOptions
}
);
const tabScreenConfig = {
Meals: {
screen: MealsNavigator,
navigationOptions: {
tabBarIcon: tabInfo => {
return (
<Ionicons name="ios-restaurant" size={25} color={tabInfo.tintColor} />
);
},
tabBarColor: Colors.primaryColor
}
},
Favorites: {
screen: FavNavigator,
navigationOptions: {
tabBarIcon: tabInfo => {
return <Ionicons name="ios-star" size={25} color={tabInfo.tintColor} />;
},
tabBarColor: Colors.accentColor
}
}
};
const MealsFavTabNavigator =
Platform.OS === "android"
? createMaterialBottomTabNavigator(tabScreenConfig, {
activeTintColor: "white",
shifting: true,
barStyle: {
backgroundColor: Colors.primaryColor
}
})
: createBottomTabNavigator(tabScreenConfig, {
tabBarOptions: {
activeTintColor: Colors.accentColor
}
});
export default createAppContainer(MealsFavTabNavigator);
Thanks in advance.
Full code:
GitHub
I had similar issue today. I salved it by downgrading/upgrading react-native-screens to version: "react-native-screens": "2.1.0". Before was 2.4

undefined is not a function (evaluating '(0,_reactnavigationstack.creactDrawernavigation)')

I want to create Drawer Navigation That contains Menu and Home Screen. I tried a lot but I am unable to resolve this issue and as per update of react native we have to wrap the navigation in CreateAppContainer, as you can see i wraped it but nothing is resolved.
"MainComponent"
import React, {Component} from 'react';
import { View, Platform } from 'react-native';
import Menu from './MenuComponent';
import Home from './HomeComponent';
import DishDetail from './DishDetailComponent';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator, createDrawerNavigator } from 'react-navigation-stack';
const MenuNavigator = createStackNavigator({
Menu: { screen: Menu },
DishDetail: { screen: DishDetail }
},
{
initialRouteName: 'Menu',
navigationOptions: {
headerStyle: {
backgroundColor: "#512DA8"
},
headerTintColor: '#fff',
headerTitleStyle: {
color: "#fff"
}
}
}
);
const HomeNavigator = createStackNavigator({
Home: { screen: Home }
}, {
navigationOptions: ({ navigation }) => ({
headerStyle: {
backgroundColor: "#512DA8"
},
headerTitleStyle: {
color: "#fff"
},
headerTintColor: "#fff"
})
});
//-----------Main---------//
const MainNavigator = createDrawerNavigator({
Home:
{ screen: HomeNavigator,
navigationOptions: {
title: 'Home',
drawerLabel: 'Home'
}
},
Menu:
{ screen: MenuNavigator,
navigationOptions: {
title: 'Menu',
drawerLabel: 'Menu'
},
}
}, {
drawerBackgroundColor: '#D1C4E9'
});
class Main extends Component() {
render() {
return(
<View>
<MainNavigator />
</View>
);
}
}
export default createAppContainer(Main);
////////////////////App.js/////////////////
import React from 'react';
import Main from './components/MainComponent';
export default class App extends React.Component {
render() {
return (
<Main />
);
}
}
I think the issue is i am not wrapping the appContainer Correctly.
You are importing wrong. use like
import { createDrawerNavigator } from 'react-navigation-drawer';
import { createStackNavigator } from 'react-navigation-stack';
instead of
import { createStackNavigator, createDrawerNavigator } from 'react-navigation-stack';
Try this way
const LoginNavigator = createStackNavigator({
Login: {
screen: Login,
navigationOptions: {
header: null,
}
},
SignUp: {
screen: SignUp,
navigationOptions: {
header: null,
}
}
});
class NavigationDrawerStructure extends Component {
toggleDrawer = () => {
//Props to open/close the drawer
this.props.navigationProps.toggleDrawer();
};
render() {
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={this.toggleDrawer.bind(this)}>
<Image
source={require('../Img/hamburger.png')}
style={{ width: 25, height: 25, marginLeft: 20, tintColor: '#ffffff' }}
/>
</TouchableOpacity>
</View>
);
}
}
const HomeActivity_StackNavigator = createStackNavigator({
Home: {
screen: Main,
navigationOptions: ({ navigation }) => ({
title: 'Dashboard',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#FF9800'
},
headerTintColor: '#fff'
}),
},
}, {headerLayoutPreset: 'center'});
const DrawerNavigators = createDrawerNavigator({
//Drawer Optons and indexing
Main: {
screen: HomeActivity_StackNavigator,
navigationOptions: {
drawerLabel: 'Dashboard',
}
}
});
const NonDrawerNavigators = createStackNavigator({
TaskView: {
screen: TaskView,
navigationOptions: {
title: 'Task',
headerStyle: {
backgroundColor: '#FF9800',
},
headerTintColor: '#fff'
}
},
TeamView: {
screen: TeamView,
navigationOptions: {
title: 'Team',
headerStyle: {
backgroundColor: '#FF9800',
},
headerTintColor: '#fff'
}
}
}, {headerLayoutPreset: 'center'});
const AppNavigator = createStackNavigator({
drawerStack: {
screen: DrawerNavigators,
navigationOptions: {
header: null
}
},
nonDrawerStack: {
screen: NonDrawerNavigators,
navigationOptions: {
header: null
}
}
});
export default createAppContainer(createSwitchNavigator({
SplashScreen: SplashScreen,
loginStack: LoginNavigator,
homeStack: AppNavigator
}, {
initialRouteName: 'SplashScreen'
})
);
I had modified your code as under. I hope this will help you.
"MainComponent"
import React, {Component} from 'react';
import { View, Platform } from 'react-native';
import Menu from './MenuComponent';
import Home from './HomeComponent';
import DishDetail from './DishDetailComponent';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator, createDrawerNavigator } from 'react-navigation-stack';
const MenuNavigator = createAppContainer(createDrawerNavigator(
{
Menu: { screen: Menu },
DishDetail: { screen: DishDetail }
},
{
contentComponent: SideMenu,
drawerWidth: normalize(280),
initialRouteName: "Menu"
}
));
const HomeNavigator = createAppContainer(createStackNavigator(
{
Home: { screen: Home }
},
{
// Default config for all screens
headerMode: 'none',
initialRouteName: 'Home',
// transitionConfig: noTransitionConfig,
},
));
class Main extends Component() {
render() {
return(
<View>
<MainNavigator />
</View>
);
}
}
export default createAppContainer(Main);
////////////////////App.js/////////////////
import React from 'react';
import Main from './components/MainComponent';
export default class App extends React.Component {
render() {
return (
<Main />
);
}
}

Switch Navigator Two headers

I've build an app with a BottomTabNavigator and createSwitchNavigator.
If I declare my screen inside the MainTabNavigator, the top header of my screens work as intended, but as soon as I import my screens (for example my HomeScreen) I get a double header.
I've tried adding:
{
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
}
To my StackNavigator, but doesn't seem to have an effect.
I've tried looking at similar posted questions, but have not been set off into the right direction.
Is anyone else familiar with this problem and how to solve it?
App JS
import React from 'react';
import { View, Text } from 'react-native';
import { createStackNavigator,createBottomTabNavigator } from 'react-navigation';
import AppNavigator from './navigation/AppNavigator';
export default class App extends React.Component {
render() {
return <AppNavigator />;
}
}
App Navigator
import React from 'react';
import { createSwitchNavigator } from 'react-navigation';
import MainTabNavigator from './MainTabNavigator';
export default createSwitchNavigator(
{
Main: MainTabNavigator,
},
);
MainTabNavigator
import React from 'react';
import { Button, Text, View } from 'react-native';
import { Ionicons } from '#expo/vector-icons';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';
import HomeScreen from '../screens/clubs/Home';
import DetailsScreen from '../screens/clubs/Details';
class SettingsScreen extends React.Component {
static navigationOptions = {
// title: ' Alpha',
header: null,
};
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details')}
/>
</View>
);
}
}
const HomeStack = createStackNavigator({
Home: { screen: HomeScreen },
Details: { screen: DetailsScreen },
});
const SettingsStack = createStackNavigator({
Settings: { screen: SettingsScreen },
Details: { screen: DetailsScreen },
});
export default createBottomTabNavigator(
{
Home: { screen: HomeStack },
Settings: { screen: SettingsStack },
},
{
navigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
let iconName;
if (routeName === 'Home') {
iconName = `ios-information-circle${focused ? '' : '-outline'}`;
} else if (routeName === 'Settings') {
iconName = `ios-information-circle${focused ? '' : '-outline'}`;
}
return <Ionicons name={iconName} size={25} color={tintColor} />;
},
}),
tabBarOptions: {
activeTintColor: '#DD016B',
inactiveTintColor: 'white',
tabStyle: {
width: 100,
backgroundColor: 'black',
},
labelStyle:{
color: 'white',
},
}
},
);
Home JS
import React, { Component } from 'react';
import {
AppRegistry,
ListView,
View,
Text,
StyleSheet,
Image,
Button,
TouchableOpacity,
TextInput,
ScrollView,
Icon,
FlatList,
} from 'react-native';
import { createStackNavigator, } from 'react-navigation';
export class HomeScreen extends Component {
static navigationOptions = {
// title: ' Alpha',
header: null,
};
....... App content
}
AppRegistry.registerComponent('App', () => App)
export default createStackNavigator({
Home: {
screen: HomeScreen,
},
},
{
initialRouteName: 'Home',
});
In your MainTabNavigator file, try this:
const HomeStack = createStackNavigator({
Home: { screen: HomeScreen, navigationOptions: { header: null } },
Details: { screen: DetailsScreen, navigationOptions: { header: null } },
});