React Navigation 6 - Icons not appearing on tabNavigator - reactjs

I am using React Navigation 6 createBottomTabNavigator and trying to provide Icon to tabBarIcon but the screen is coming up blank. and if I don't provide any icon then a box with a cross is coming Below is my code
import {createBottomTabNavigator} from '#react-navigation/bottom-tabs';
import Home from '../screens/app/home';
import Login from '../screens/auth/login';
import {Icon} from 'react-native-elements';
import Ionicons from 'react-native-vector-icons/Ionicons';
const Tab = createBottomTabNavigator();
const TabNavigator = () => {
return (
<Tab.Navigator
screenOptions={{
tabBarShowLabel: false,
tabBarStyle: {backgroundColor: 'cyan'},
}}>
<Tab.Screen
options={{
tabBarIcon: ({color, size}) => {
<Ionicons name="logo-bitcoin" />;
},
}}
name="Home"
component={Home}
/>
<Tab.Screen
options={{
tabBarIcon: ({color, size}) => {
<Icon
type="font-awesome-5"
name="coins"
color={color}
size={size}
/>;
},
}}
name="Login"
component={Login}
/>
<Tab.Screen name="Login2" component={Login} />
</Tab.Navigator>
);
};
export default TabNavigator;
p.s. - I've tried including apply from: "../../node_modules/react-native-vector-icons/fonts.gradle" in my android/app/build.gradle

you miss RETURN in "tabBarIcon"
tabBarIcon: ({color, size}) => {
return <Ionicons name="logo-bitcoin" />;
},
or without return
tabBarIcon: ({color, size}) => <Ionicons name="logo-bitcoin" />

Related

How can I remove the rounded shape around my selected tab text?

I just start learning React Native, and I added my bottom nav using Material Bottom Tabs.
My only issue is this purple circle around my icon when selected. I checked the docs looking for this default setting but couldn't find it.
Here is my code:
const Tab = createMaterialBottomTabNavigator();
const App = () => {
const [loaded] = useFonts({
InterBold: require("./assets/fonts/Inter-Bold.ttf"),
InterSemiBold: require("./assets/fonts/Inter-SemiBold.ttf"),
InterMedium: require("./assets/fonts/Inter-Medium.ttf"),
InterRegular: require("./assets/fonts/Inter-Regular.ttf"),
InterLight: require("./assets/fonts/Inter-Light.ttf"),
});
if (!loaded) return null;
return (
<NavigationContainer theme={theme}>
<Tab.Navigator initialRouteName="Menu principal"
activeColor="#f0edf6"
inactiveColor="white"
barStyle={{ backgroundColor: 'black' }}
>
<Tab.Screen name="Menu principal" component={Home}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="home" color={color} size={26} />
),
}}
/>
<Tab.Screen name="Collections" component={Collections}
options={{
tabBarLabel: 'Collections',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="cards" color={color} size={26} />
),
}}
/>
<Tab.Screen name="Associations" component={Associations}
options={{
tabBarLabel: 'Associations',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="account-group" color={color} size={26} />
),
}}
/>
<Tab.Screen name="Classement" component={Classement}
options={{
tabBarLabel: 'Classement',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="trophy" color={color} size={26} />
),
}}
/>
<Tab.Screen name="News" component={News}
options={{
tabBarLabel: 'News',
tabBarIcon: ({ color }) => (
<MaterialCommunityIcons name="newspaper" color={color} size={26} />
),
}}
/>
</Tab.Navigator>
Here is the solution I found. You have to npm install react-native-paper, import, and use it.
To use react-native-paper to change the little circle tab buttons, wrap <Tab.Navigator>...</Tab.Navigator> with <PaperProvider theme={theme}> as shown below.
Finally, create a const theme like I did, and change the secondaryContainer to whatever color you want.
P.S. make sure to change your import names as shown to not conflict with the Provider for redux.
import {
MD3LightTheme as DefaultTheme,
Provider as PaperProvider,
} from "react-native-paper";
const Tab = createMaterialBottomTabNavigator();
const theme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
secondaryContainer: "red",
},
};
const App = () => {
return (
<NavigationContainer>
<PaperProvider theme={theme}>
<Tab.Navigator initialRouteName="Menu principal"
activeColor="#f0edf6"
inactiveColor="white"
barStyle={{ backgroundColor: 'black' }}
>
// rest of your code
</Tab.Navigator>
</PaperProvider>
</NavigationContainer>
)
}

is there any method to re-render the screen to bottom tab nav v5 in react-native

Hy, I'm using react-native bottom tabs navigation the first time I'm having an issue to re-render the screen when I get back to some other tab. I try to use isFocused in useEffect() but it didn't work for me.
const LandScreen = ({navigation}) => {
return (
<Tab.Navigator
tabBarOptions={{
showLabel: false,
activeTintColor: colors.primary,
inactiveTintColor: colors.textHead,
}}
>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({focused, color, size}) => {
const icon = focused ? 'home' : 'home';
return <Icon name={icon} color={color} size={size} />;
},
}}
/>
<Tab.Screen
name="Message"
component={ChatStackScreen}
options={{
tabBarIcon: ({focused, color, size}) => {
const icon = focused ? 'chatbox-ellipses' : 'chatbox-ellipses';
return <Icon name={icon} color={color} size={size} />;
},
}}
/>
<Tab.Screen
name="Requests"
component={RequestStackScreen}
options={{
tabBarIcon: ({focused, color, size}) => {
const icon = focused ? 'heart' : 'heart';
return <Icon name={icon} color={color} size={size} />;
},
}}
/>
<Tab.Screen
name="Notifications"
component={NotificationStackScreen}
options={{
tabBarIcon: ({focused, color, size}) => {
const icon = focused ? 'notifications' : 'notifications';
return <Icon name={icon} color={color} size={size} />;
},
}}
/>
<Tab.Screen
name="Profile"
component={ProfileScreenScreen}
options={{
tabBarIcon: ({focused, color, size}) => {
const icon = focused ? 'person' : 'person';
return <Icon name={icon} color={color} size={size} />;
},
}}
/>
</Tab.Navigator>
);
};
Each Tab component having a stack inside of it.
Someone informs me how to rerender the bottom navigation tabs?
If I understand you correctly, you want the screen to re-render when you click on a bottom tab navigation button.
This can be accomplished by either adding the 'focus' event listener via the react navigation docs https://reactnavigation.org/docs/function-after-focusing-screen/
Or by explicitly calling 'navigation.navigate' when a bottom tab is pressed.
Assuming I understand your question, all you want to do is re-render the icons when the tab changes?
React Navigation has docs & an example for this use-case for tab-based navigation here.
Posting the code sample from the docs here for ease-of-access:
import Ionicons from 'react-native-vector-icons/Ionicons';
// (...)
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused
? 'ios-information-circle'
: 'ios-information-circle-outline';
} else if (route.name === 'Settings') {
iconName = focused ? 'ios-list-box' : 'ios-list';
}
// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: 'tomato',
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
If your question meant re-rendering the screen when the tab changes:
Leveraging useEffect with useIsFocused should work when changing tabs. You haven't included your example with those hooks, so I'm not exactly sure how you're using it.
The following snippet should get you up and running with said hooks. In this case, you can run whatever you want inside the useEffect when switching tabs, where the active tab gets triggered.
If for some reason you just want the UI to get updated/persisted based on some data between tab changes you might want to consider using Redux.
import React, { useEffect } from "react";
import { Text, View } from "react-native";
import { NavigationContainer } from "#react-navigation/native";
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs";
import { useIsFocused } from "#react-navigation/core";
function HomeScreen() {
const isFocused = useIsFocused();
useEffect(() => {
if (isFocused) {
console.log("HELLO HOME");
}
}, [isFocused]);
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Home!</Text>
</View>
);
}
function SettingsScreen() {
const isFocused = useIsFocused();
useEffect(() => {
if (isFocused) {
console.log("HELLO SETTINGS");
}
}, [isFocused]);
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Settings!</Text>
</View>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}

How can i customize react navigation v5 material bottom navigator?

I was trying to customize my material bottom navigation tab but there is not enough resource on the internet as far as i searched. Can you help me with this problem?
Here is my current bottom navigation tab:
import { createMaterialBottomTabNavigator } from '#react-navigation/material-bottom-tabs';
interface IAppTabsProps extends IAppStackNavigationProps<'AppTabs'> {}
const Tabs = createMaterialBottomTabNavigator<AppTabsParamList>();
const AppTabs: React.FC<IAppTabsProps> = () => {
return (
<Tabs.Navigator labeled keyboardHidesNavigationBar initialRouteName="Home" shifting sceneAnimationEnabled>
<Tabs.Screen
name="Home"
component={Home}
options={{
tabBarIcon: ({ focused, ...props }) => (
<Ionicons name={focused ? 'home' : 'home-outline'} size={24} {...props} />
),
tabBarBadge: true,
tabBarLabel: 'Home',
}}
/>
<Tabs.Screen
name="Profile"
component={Profile}
options={{
tabBarIcon: props => <Ionicons name="ios-person" size={24} {...props} />,
tabBarLabel: 'Profile',
}}
/>
<Tabs.Screen
name="Notifications"
component={Notifications}
options={{
tabBarIcon: ({ focused, ...props }) => (
<FontistoIcons name={focused ? 'bell-alt' : 'bell'} size={24} {...props} />
),
tabBarLabel: 'Notifications',
tabBarBadge: 4,
}}
/>
<Tabs.Screen
name="Preferences"
component={Preferences}
options={{
tabBarIcon: props => <SimpleLineIcons name="settings" size={24} {...props} />,
tabBarLabel: 'Preferences',
}}
/>
</Tabs.Navigator>
);
};

How to space around top tab bar in react native?

I am working on a dummy project for practice using react navigation material top tab. Everything is working fine, I just want to know is there any way to space around the tabs? I attached the output image of my code
Here is my code
import * as React from "react";
import { createDrawerNavigator } from "#react-navigation/drawer";
import AccountsScreen from "../screens/AccountsScreen";
import FavouritesScreen from "../screens/FavouritesScreen";
import HomeScreen from "../screens/HomeScreen";
import SettingsScreen from "../screens/SettingsScreen";
import TrendsScreen from "../screens/TrendsScreen";
import { createMaterialTopTabNavigator } from "#react-navigation/material-top-tabs";
import { Dimensions } from "react-native";
import Income from "../screens/Income";
import Expense from "../screens/Expense";
const Drawer = createDrawerNavigator();
const Tab = createMaterialTopTabNavigator();
CategoriesTabScreens = () => {
return (
<Tab.Navigator
initialRouteName="Income"
tabBarOptions={{
indicatorStyle: {
height: Dimensions.get("window").height,
backgroundColor: "#29416F",
},
activeTintColor: "#fff",
inactiveTintColor: "#333",
}}
>
<Tab.Screen name="Income" component={Income} />
<Tab.Screen name="Expense" component={Expense} />
</Tab.Navigator>
);
};
const AppDrawer = () => {
return (
<Drawer.Navigator
initialRouteName="Home"
screenOptions={{
headerShown: true,
}}
>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Accounts" component={AccountsScreen} />
<Drawer.Screen name="Categories" component={CategoriesTabScreens} />
<Drawer.Screen name="Trends" component={TrendsScreen} />
<Drawer.Screen name="Favourites" component={FavouritesScreen} />
<Drawer.Screen name="Settings" component={SettingsScreen} />
</Drawer.Navigator>
);
};
export default AppDrawer;
Output
the result I want
Just use Style prop in Tab.navigator
Here is snack
https://snack.expo.io/#anthowm/drawer-navigation-%7C-react-navigation
const Tab = createMaterialTopTabNavigator();
const CategoriesTabScreens = () => {
return (
<Tab.Navigator
initialRouteName="Income"
tabBarOptions={{
indicatorStyle: {
height: Dimensions.get("window").height,
backgroundColor: "#29416F",
},
activeTintColor: "#fff",
inactiveTintColor: "#333",
}}
style={{paddingHorizontal: 24, marginTop: 40}}
>
<Tab.Screen name="Income" component={() => (<View style={{marginTop: 20}}><Text>INCOME</Text></View>)} />
<Tab.Screen name="Expense" component={() => (<View style={{marginTop: 20}}><Text>EXPENSE</Text></View>)} />
</Tab.Navigator>
);
};

issue with tabBarIcon in react navigation v5

I want to set an icon for tab navigation but it returns an error
This is my code:
<Tab.Screen name="Home" component={Home} options={{tabBarIcon:'home'}} />
This is the error i get:
How can i fix this?
You must set showIcon property to true in tabBarOptions like this:
<Tab.Navigator tabBarOptions={{ showIcon: true }}>
and then you can set the icon for your screen like this:
<Tab.Screen name="Home" component={HomeScreen} options={{ tabBarIcon:(tabInfo) => (<MaterialIcons name="home" size={18} color={tabInfo.tintColor} />)}}/>
full code example:
import React from "react";
import { createMaterialTopTabNavigator } from "#react-navigation/material-top-tabs";
import HomeScreen from "../screens/HomeScreen";
import { MaterialIcons } from "#expo/vector-icons";
const Tab = createMaterialTopTabNavigator();
const MyTabs = (props) => {
return (
<Tab.Navigator
tabBarOptions={{ showIcon: true, showLabel: false }}
>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: (tabInfo) => (
<MaterialIcons name="home" size={18} color={tabInfo.tintColor} />
),
}}
/>
</Tab.Navigator>
);
};
export default MyTabs;
Just as one of the solutions given above, we can create a TabBarIcon component and gave it the props of name and focused.
import React from "react"
import { Ionicons } from "#expo/vector-icons"
export default function TabBarIcon({ name, focused }) {
return (
<Ionicons
name={name}
size={25}
color={focused ? "tomato" : "black"}
style={{ marginBottom: -10 }}
/>
)
}
Then import it in the App.js file and on the tabBarIcon option, return the TabBarIcon component
import { StatusBar } from "expo-status-bar"
import React from "react"
import { NavigationContainer } from "#react-navigation/native"
import { createBottomTabNavigator } from "#react-navigation/bottom-tabs"
import { StyleSheet } from "react-native"
import HomeScreen from "./app/screens/HomeScreen"
import TabBarIcon from "./app/components/TabBarIcon"
const Tab = createBottomTabNavigator()
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
tabBarOptions={{
showIcon: true,
activeTintColor: "tomato",
inactiveTintColor: "gray",
labelStyle: {
fontSize: 12,
padding: 10,
},
}}
>
<Tab.Screen
initialRouteName="Home"
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={Platform.OS === "ios" ? `ios-home` : "md-home"}
/>
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
)
}
You need to import the real way (TabBarIcon file)
import React from 'react';
import { Ionicons } from '#expo/vector-icons';
export default function TabBarIcon(props) {
return (
<Ionicons
name={props.name}
size={26}
color={props.focused ? 'red' : 'black'}
style={{ marginBottom: -3 }}
/>
);
}
and you need to select the right icon (ios and md)(Part of router.js)
import React from "react";
import { Platform } from "react-native";
import { createStackNavigator } from 'react-navigation-stack';
import { createBottomTabNavigator } from "react-navigation-tabs";
import { createSwitchNavigator } from 'react-navigation';
import TabBarIcon from "./components/TabBarIcon";
import Home from './components/Home';
import Register from './components/Register'
// Home page
const HomeStack = createStackNavigator({
Home: Home,
});
HomeStack.navigationOptions = {
tabBarIcon: ({ focused }) => (
<TabBarIcon
focused={focused}
name={
Platform.OS === 'ios'
? `ios-home`
: 'md-home'
}
/>
),
};
HomeStack.path = '';
Even though I tried what was described above in the answers I was still getting the label shown in the tab bar. It only disappeared when I added labeled={false} as a prop to the Navigator.
Example
<Tab.Navigator
initialRouteName="Home"
labeled={false}
sceneAnimationEnabled={false}
>
etc
</Tab.Navigator>
Here it is:
import Icon from 'react-native-vector-icons/Ionicons';
<Tab.Screen
name="Home"
component={Home}
options={{
tabBarIcon: ({ focused, color }) => (
<Text style={{ marginTop: 6 }}> // Your Style Here
<Icon name={'md-add-circle'} color={color} />
</Text>
)
}}
/>
I hope you like it!!!

Resources