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

导入SVG至BottomTabNavigator时出现元素类型无效错误,如何解决?

SVG导入BottomTabNavigator时渲染错误的解决方法

问题描述

将SVG文件导入BottomTabNavigator时,出现以下渲染错误:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: number.

已安装react-native-svg和react-native-svg-transformer,并添加了index.d.ts文件,内容为declare module '*.svg';。

相关代码

src/components/BottomTabNavigator.tsx

import React, {FC} from 'react';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import screens from '../screens/';
import {BottomTabNavigatorIcons} from '../assets';
  
const Tab = createBottomTabNavigator();  

const bottomTabNavigatorOptions = [
    {
        id: 'search',
        name: 'Search',
        component: screens.SearchScreen,
        icon: BottomTabNavigatorIcons.defaultIcon.searchIcon,
    },
    {
        id: 'record',
        name: 'Record',
        component: screens.RecordScreen,
        icon: BottomTabNavigatorIcons.defaultIcon.recordIcon,
    },
    {
        id: 'profile',
        name: 'Profile',
        component: screens.ProfileScreen,
        icon: BottomTabNavigatorIcons.defaultIcon.profileIcon,
    },
];

export const BottomTabNavigator: FC = () => {
    return (
        <>
            <Tab.Navigator screenOptions={{headerShown: false}}>
                {bottomTabNavigatorOptions.map(screen => (
                    <Tab.Screen
                        key={screen.id}
                        name={screen.name}
                        component={screen.component}
                        options={{
                            tabBarIcon: () => <screen.icon />,
                        }}
                    />
               ))}
            </Tab.Navigator>
        </>
    );
};

src/assets/index.ts

import ProfileIcon from './bottom-navigation/profile.svg';
import RecordIcon from './bottom-navigation/record.svg';
import SearchIcon from './bottom-navigation/search.svg';

const BottomTabNavigatorIcons = {
    defaultIcon: {
        profileIcon: ProfileIcon,
        recordIcon: RecordIcon,
        searchIcon: SearchIcon,
    },
};

export {BottomTabNavigatorIcons};

调试信息

console.log(bottomTabNavigatorOptions)输出显示icon字段为数字:

[{"component": [Function SearchScreen], "icon": 3, "id": "search", "name": "Search"}, {"component": [Function RecordScreen], "icon": 2, "id": "record", "name": "Record"}, {"component": [Function ProfileScreen], "icon": 1, "id": "profile", "name": "Profile"}]

问题原因

  1. SVG转换器配置未生效:icon字段输出数字,说明SVG文件未被正确转换为React组件,而是被当作静态资源(数字为资源ID)导入。
  2. 组件渲染语法错误:JSX要求组件名称必须以大写字母开头,<screen.icon />的写法不符合规范,无法正确识别为组件。

解决步骤

步骤1:完善react-native-svg-transformer配置

修改项目的metro.config.js(或metro.config.ts),确保SVG转换器正确生效:

const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');

module.exports = mergeConfig(getDefaultConfig(__dirname), {
  transformer: {
    babelTransformerPath: require.resolve('react-native-svg-transformer'),
  },
  resolver: {
    assetExts: getDefaultConfig(__dirname).resolver.assetExts.filter(ext => ext !== 'svg'),
    sourceExts: [...getDefaultConfig(__dirname).resolver.sourceExts, 'svg'],
  },
});

同时更新index.d.ts,让TypeScript正确识别SVG类型:

declare module '*.svg' {
  import React from 'react';
  import { SvgProps } from 'react-native-svg';
  const content: React.FC<SvgProps>;
  export default content;
}

步骤2:修复Tab.Screen的组件渲染代码

将tabBarIcon中的动态组件渲染方式修改为符合JSX规范的写法:

options={{
  tabBarIcon: () => {
    const Icon = screen.icon;
    return <Icon />;
  },
}}

或直接使用React.createElement:

options={{
  tabBarIcon: () => React.createElement(screen.icon),
}}

步骤3:重启Metro服务

修改配置后,必须重置缓存并重启Metro bundler:

npx react-native start --reset-cache

验证

重启服务后重新运行项目,console.log(bottomTabNavigatorOptions)中的icon字段应显示为[Function Component],此时TabBar的SVG图标可正常渲染,不会再出现类型错误。

内容的提问来源于stack exchange,提问作者alski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:55:16