You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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项配置:

  1. 修正Details项配置

    • 移除type字段(自定义组件无需Ionicons类型)
    • 确保自定义图标组件首字母大写(React组件规范),并正确导入
    • 给激活/未激活状态的图标设置差异化样式(比如颜色)
  2. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 01:13:18