React Native自定义底部导航栏:如何添加SVG作为图标?
React Native 自定义底部导航栏 Details 项配置修复
问题描述
我是React和React Native新手,正在制作自定义底部导航栏,已完成其他图标的添加,但在配置Details页面的导航项时遇到问题。当前代码如下:
// tab array const TabArr = [ { route: Screen1,label: 'Screen1',type: Ionicons, activeIcon: 'book',inActiveIcon: 'book-outline', component: ScreenOne }, { route: 'Details',label: 'Details',type: Ionicons, activeIcon: <logo width="100%" height="70%" />, inActiveIcon: <logo width="100%" height="70%" />, component: DetailsScreen }, { route: Screen3,label: 'Screen3',type: Ionicons, activeIcon: 'book',inActiveIcon: 'book-outline', component: ScreenThree } ] const Tab = createBottomTabNavigator() const TabButton = (props) => { const { item, onPress, accessibilityState } = props const focused = accessibilityState.selected return ( <TouchableOpacity onPress={onPress} activeOpacity={1} style={styles.container} > <View style={styles.container}> <Icon type={item.type} name={focused ? item.activeIcon : item.inActiveIcon} color={focused ? 'blue' : 'red'} /> </View> </TouchableOpacity> ) } export default function MainContainer({ navigation }) { return ( <NavigationContainer> <Tab.Navigator screenOptions={{ headerShown: false, tabBarStyle: { } }} > {TabArr.map((item, index) => { return ( <Tab.Screen key={index} name={item.route} component={item.component} options={{ tabBarShowLabel: false, tabBarButton: (props) => <TabButton {...props} item={item} /> }} /> ) })} </Tab.Navigator> </NavigationContainer> ) }
需要解决Details导航项的配置问题:route: 'Details',label: 'Details',type: , activeIcon: , inActiveIcon: , component: DetailsScreen
修复方案
核心问题是TabButton仅适配了基于名称的Ionicons图标,而Details项用的是自定义React组件,需要调整组件兼容两种图标类型,同时修正Details项配置:
修正Details项配置
- 移除
type字段(自定义组件无需Ionicons类型) - 确保自定义图标组件首字母大写(React组件规范),并正确导入
- 给激活/未激活状态的图标设置差异化样式(比如颜色)
- 移除
修改TabButton组件
添加判断逻辑:如果图标是React元素则直接渲染,否则用Icon组件加载图标
修改后的完整代码:
// 导入自定义图标组件,注意首字母大写 import Logo from './components/Logo'; import Ionicons from '@expo/vector-icons/Ionicons'; import { Icon } from '@rneui/themed'; // tab array const TabArr = [ { route: 'Screen1', // 改为字符串,确保与Tab.Screen的name一致 label: 'Screen1', type: Ionicons, activeIcon: 'book', inActiveIcon: 'book-outline', component: ScreenOne }, { route: 'Details', label: 'Details', activeIcon: <Logo width="100%" height="70%" style={{color: 'blue'}} />, inActiveIcon: <Logo width="100%" height="70%" style={{color: 'red'}} />, component: DetailsScreen }, { route: 'Screen3', // 改为字符串 label: 'Screen3', type: Ionicons, activeIcon: 'book', inActiveIcon: 'book-outline', component: ScreenThree } ]; const Tab = createBottomTabNavigator(); const TabButton = (props) => { const { item, onPress, accessibilityState } = props; const focused = accessibilityState.selected; const currentIcon = focused ? item.activeIcon : item.inActiveIcon; return ( <TouchableOpacity onPress={onPress} activeOpacity={1} style={styles.container} > <View style={styles.container}> {/* 兼容自定义组件图标和Ionicons图标 */} {React.isValidElement(currentIcon) ? ( currentIcon ) : ( <Icon type={item.type} name={currentIcon} color={focused ? 'blue' : 'red'} /> )} </View> </TouchableOpacity> ); }; export default function MainContainer({ navigation }) { return ( <NavigationContainer> <Tab.Navigator screenOptions={{ headerShown: false, tabBarStyle: {} }} > {TabArr.map((item, index) => ( <Tab.Screen key={index} name={item.route} component={item.component} options={{ tabBarShowLabel: false, tabBarButton: (props) => <TabButton {...props} item={item} /> }} /> ))} </Tab.Navigator> </NavigationContainer> ); }
关键说明
- 组件规范:React组件必须首字母大写,所以将
<logo />改为<Logo />并确保正确导入 - 路由一致性:
route字段使用字符串,避免变量未定义问题,确保与Tab.Screen的name属性匹配 - 图标兼容:通过
React.isValidElement判断图标类型,同时支持自定义组件和图标库图标 - 视觉统一:直接在自定义图标上设置激活/未激活样式,与其他导航项保持视觉一致
内容的提问来源于stack exchange,提问作者Jen
相关产品推荐
相关产品推荐

