I am currently trying to implement a custom tabBar design into my react native app which is using React Navigation 5 as the navigation library. Everything is working correctly, except that my tabBarIcons don't receive any props, so i cannot determine whether i have to show the active or inactive tabIcon. Whenever i use a default tabbar i do receive the props, so there must be something wrong in my custom tabbar. I did follow the docs though, and only find the instruction to emit the 'tabPress' event. I do however think that i should emit more events to get the correct focused prop. I have set up the navigator like this:
const Tabs = createBottomTabNavigator();
export default () => (
<Tabs.Navigator tabBar={TabBarComponent} initialRouteName="Home">
<Tabs.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({ focused }) => {
// The props here are {}, so focused is undefined.
const icon = focused
? require('images/iconOverviewRed.png')
: require('images/iconOverviewGrey.png');
return <Image source={icon} />;
},
}}
/>
<Tabs.Screen
name="Overview"
component={OverviewScreen}
options={{
tabBarIcon: props => {
console.log(props);
return <Image source={require('images/logoRed.png')} />;
},
}}
/>
<Tabs.Screen
name="Account"
component={AccountScreen}
options={{
tabBarIcon: ({ focused }) => {
const icon = focused
? require('images/iconAccountRed.png')
: require('images/iconAccountGrey.png');
return <Image source={icon} resizeMethod="resize" />;
},
}}
/>
</Tabs.Navigator>
);
And this is my custom tabBar compnent:
const TabBar = ({ navigation, state, descriptors }: any) => {
return (
<View style={styles.container}>
{state.routes.map((route: any) => {
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!event.defaultPrevented) {
navigation.dispatch({
...TabActions.jumpTo(route.name),
target: state.key,
});
}
};
return (
<TabIcon
key={route.key}
Icon={descriptors[route.key].options.tabBarIcon}
onPress={onPress}
isBig={route.name === 'Home'}
/>
);
})}
</View>
);
};
const TabIcon = ({ onPress, Icon, key, isBig }: any) => {
return (
<TouchableWithoutFeedback key={key} onPress={onPress}>
<View style={isBig ? styles.bigTab : styles.defaultTab} key={key}>
<Icon />
</View>
</TouchableWithoutFeedback>
);
};
Thanks in advance.
descriptors[route.key].options
just gives you the options as you have specified them. If you log the value of descriptors[route.key].options.tabBarIcon
, you'll see that it prints the function that you have specified.
In your custom tab bar, it's upto you to use the option as you need. Since it's a function here, you'll have to call it and pass desired arguments.
descriptors[route.key].options.tabBarIcon({ focused: state.index === index })
This also means that you fully control the option. You can put whatever type you'd like, function, a require statement directly etc. and then use that. You also don't have to call it tabBarIcon
, you can call it whatever you want.