4

I'm using different types of react native vector icons - Material and FontAwesome depending on availability of a particular icon. I wanted to create a common component that wraps usage of the icons across the app. So far I have:

import React from 'react'; import Icon from "react-native-vector-icons/FontAwesome"; import {theme} from "../../../styles/style"; /** * Common reusable icon component * @param props * @returns {*} */ const icon = (props) => { return ( <Icon size={theme.SIZE_ICON} color={theme.BACKGROUND_ICON_COLOR} {...props} style={props.style}/> ); }; export default icon; 

Which works only for FontAwesome, how can I make it dynamic based on e.g. prop parameter so I can use Material icons when I need to? Note: I wouldn't like to create separate components for each type e.g. IconMaterial, IconFontAwesome etc. I want the name of the component to be Icon regardless of type. Is that possible?

6 Answers 6

4

You could pass a prop called iconFamily to your icon component:

Inside your Icon Component you are importing all the Fonts you want to use, e.g.:

import IconFA from "react-native-vector-icons/FontAwesome"; import IconMA from "react-native-vector-icons/Material"; 

Then inside Icon's render function:

 const Icon = (props) => { renderIcon = () => { if (props.iconFamily == "FA") { return ( <IconFA size={23} {...props} style={props.style}/> ); } if (props.iconFamily == "MA") { return ( <IconMA size={23} {...props} style={props.style}/> ); } } return ( renderIcon() ) } 

An when you are using your custom icon component you just have to specify the iconFamily prop:

 <Icon iconFamily="FA" name="home" color="green" /> <Icon iconFamily="MA" name="code" color="red" /> 

Output:

output

Complete Working Example:

https://snack.expo.io/@tim1717/humiliated-hummus

Sign up to request clarification or add additional context in comments.

Comments

2

I always liked doing it that way. ~/components/VectorIcons.js

import AntDesign from 'react-native-vector-icons/AntDesign' import Entypo from 'react-native-vector-icons/Entypo' import EvilIcons from 'react-native-vector-icons/EvilIcons' import Feather from 'react-native-vector-icons/Feather' import FontAwesome from 'react-native-vector-icons/FontAwesome' import FontAwesome5 from 'react-native-vector-icons/FontAwesome5' import FontAwesome5Pro from 'react-native-vector-icons/FontAwesome5Pro' import Fontisto from 'react-native-vector-icons/Fontisto' import Foundation from 'react-native-vector-icons/Foundation' import Ionicons from 'react-native-vector-icons/Ionicons' import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons' import MaterialIcons from 'react-native-vector-icons/MaterialIcons' import Octicons from 'react-native-vector-icons/Octicons' import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons' import Zocial from 'react-native-vector-icons/Zocial' const VectorIcon = { AntDesign, Entypo, EvilIcons, Feather, FontAwesome, FontAwesome5, FontAwesome5Pro, Fontisto, Foundation, Ionicons, MaterialCommunityIcons, MaterialIcons, Octicons, SimpleLineIcons, Zocial, } export default VectorIcon 

To use in any jsx ~/pages/Home/index.jsx

import VectorIcon from '../../components/VectorIcon' return ( <> // ... <VectorIcon.AntDesign name="home" /> <VectorIcon.Fontisto name="clock-outline" /> </> ) 

Comments

0

This is my Icon Component, and maybe you can get an idea from this.

import React, { useEffect, useState } from "react"; import { Ionicons, AntDesign, Entypo, EvilIcons, Feather, FontAwesome, FontAwesome5, Fontisto, Foundation, MaterialCommunityIcons, MaterialIcons, Octicons, SimpleLineIcons, Zocial, } from "@expo/vector-icons"; const Icon= ({ family, name, ...props }) => { let Family; switch (family) { case "AntDesign": Family = AntDesign; break; case "Entypo": Family = Entypo; break; case "EvilIcons": Family = EvilIcons; break; case "Feather": Family = Feather; break; case "FontAwesome": Family = FontAwesome; break; case "FontAwesome5": Family = FontAwesome5; break; case "Fontisto": Family = Fontisto; break; case "Foundation": Family = Foundation; break; case "Ionicons": Family = Ionicons; break; case "MaterialCommunityIcons": Family = MaterialCommunityIcons; break; case "MaterialIcons": Family = MaterialIcons; break; case "Octicons": Family = Octicons; break; case "SimpleLineIcons": Family = SimpleLineIcons; break; case "Zocial": Family = Zocial; break; default: Family = Ionicons; } return ( <Family name={name ? name : "help-outline"} color={"#000"} size={20} {...props} /> ); }; export default Icon; 

And to use it you can do this.

<Icon family="Ionicons" name="add-outline" color={"#333"} size={30} /> 

I add the default family and name to avoid errors.

Comments

0

You can use react-native-dynamic-vector-icons

https://github.com/WrathChaos/react-native-dynamic-vector-icons

import Icon, { IconType } from "react-native-dynamic-vector-icons"; <Icon name="github" type={IconType.AntDesign} size={30} color="purple" onPress={() => {}} /> 

Comments

0

i Found a great solution i make a seperate component and in the component i just pass iconLibrary name and icon name and icon color as a props

import {View} from 'react-native'; import React, {FC} from 'react'; //here is the import icon libraries import AntDesign from 'react-native-vector-icons/AntDesign'; import Entypo from 'react-native-vector-icons/Entypo'; import EvilIcons from 'react-native-vector-icons/EvilIcons'; import Feather from 'react-native-vector-icons/Feather'; import FontAwesome from 'react-native-vector-icons/FontAwesome'; import FontAwesome5 from 'react-native-vector-icons/FontAwesome5'; import Fontisto from 'react-native-vector-icons/Fontisto'; import Foundation from 'react-native-vector-icons/Foundation'; import Ionicons from 'react-native-vector-icons/Ionicons'; import MaterialIcons from 'react-native-vector-icons/MaterialIcons'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import Octicons from 'react-native-vector-icons/Octicons'; import Zocial from 'react-native-vector-icons/Zocial'; import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons'; interface myIcon { iconLibrary: string; iconName: string; iconColor: string; } const VectorIcon: FC<myIcon> = ({iconLibrary, iconName, iconColor}) => { return ( <View> {iconLibrary === 'AntDesign' && ( <AntDesign name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'Entypo' && ( <Entypo name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'EvilIcons' && ( <EvilIcons name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'Feather' && ( <Feather name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'FontAwesome' && ( <FontAwesome name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'FontAwesome5' && ( <FontAwesome5 name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'Fontisto' && ( <Fontisto name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'Foundation' && ( <Foundation name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'Ionicons' && ( <Ionicons name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'MaterialIcons' && ( <MaterialIcons name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'MaterialCommunityIcons' && ( <MaterialCommunityIcons name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'Octicons' && ( <Octicons name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'Zocial' && ( <Zocial name={iconName} size={20} color={iconColor} /> )} {iconLibrary === 'SimpleLineIcons' && ( <SimpleLineIcons name={iconName} size={20} color={iconColor} /> )} </View> ); }; export default VectorIcon;

where we want to use

 <VectorIcon iconColor={iconColor} iconLibrary={iconLibrary} iconName={iconName} />

Comments

0

I use a "generic" Icon wrapper component

import React from 'react'; import Feather from 'react-native-vector-icons/Feather'; import FontAwesome from 'react-native-vector-icons/FontAwesome'; import FontAwesome6 from 'react-native-vector-icons/FontAwesome6'; type IconProps = { name: string; size?: number; color?: string; }; const ICONS = { fa: FontAwesome, fa6: FontAwesome6, fe: Feather, } as const; type IconPackName = keyof typeof ICONS; const Icon: React.FC<IconProps> = ({name, size, color}) => { const [packName, iconName] = name.split('/'); if (!packName || !(packName in ICONS) || !iconName) { return null; } const IconComponent = ICONS[packName as IconPackName]; return React.createElement(IconComponent, {name: iconName, size, color}); }; export default Icon;

Example of usage:

<Icon name="fe/x" size={25} color="#58508d" />

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.