When building a custom Tab.Screen
I've tried to pass a custom tabBarIcon
. While the icon renders it will not navigate to the component TestScreen
. In the docs for tabBarIcon
my understanding the Tab.Screen
should be written as:
<Tab.Screen
name={routes.FOO}
component={TestScreen}
options={{
tabBarIcon: ({ focused }) => (
<TouchableOpacity>
<View style={styles.actionButton}>
<Image source={plus} style={styles.imageIcon} />
</View>
</TouchableOpacity>
),
}}
/>
When I omit the options
:
<Tab.Screen
name={routes.FOO}
component={TestScreen}
/>
the onClick
renders the component when clicked. When I read the docs for Options for screens it mentions screenOptions
should be passed on the Navigator or Group. I tried to see if I could find a similar Q&A:
- React native react-navigation tabBarIcon does not display
- Why Is My Component not Rendering Within my Tab.Screen?
but I was unable to see where my error is.
My current dependencies:
"dependencies": {
"@react-navigation/bottom-tabs": "^6.0.5",
"@react-navigation/native": "^6.0.2",
"expo": "~42.0.1",
"expo-status-bar": "~1.0.4",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-42.0.0.tar.gz",
"react-native-gesture-handler": "^1.10.3",
"react-native-safe-area-context": "3.2.0",
"react-native-screens": "~3.4.0",
"react-native-web": "~0.13.12"
},
"devDependencies": {
"@babel/core": "^7.9.0"
},
How can I get my custom icon to render and navigate to the correct component?
CodePudding user response:
Your TouchableOpacity
is overlap with react navigation internal press handler, just wrap your icon with View
If you want customize press behavior of tab icon pass the listener object to listener
props https://reactnavigation.org/docs/navigation-events/#listeners-prop-on-screen
CodePudding user response:
Leaving this as an answer hoping it helps someone else down the road. After sleeping on this I examined my Tab.Screen
again and I remembered for a TouchableOpacity
to work it needed an onPress
even though I was thinking the parent would take care of the navigation but this wasn't the case.
While this answer is somewhat accurate, with removing the TouchableOpacity
, it would make the icon work, code:
<Tab.Screen
name={routes.FOO}
component={TestScreen}
options={{
tabBarIcon: ({ focused }) => (
<View style={styles.actionButton}>
<Image source={plus} style={styles.imageIcon} />
</View>
),
}}
/>
but it defeats the purpose of a custom button and the opacity change. After looking closer at options
I wondered what if I passed down the navigation
to onPress
and used navigate
?
Well it worked and I was left with:
<Tab.Screen
name={routes.FOO}
component={TestScreen}
options={({ navigation }) => ({
tabBarIcon: () => (
<TouchableOpacity onPress={() => navigation.navigate(routes.FOO)}>
<View style={styles.actionButton}>
<Image source={plus} style={styles.imageIcon} />
</View>
</TouchableOpacity>
),
})}
/>