'React native vector icons - dynamic type
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?
Solution 1:[1]
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" />
</>
)
Solution 2:[2]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Rafael InĂ¡cio |
| Solution 2 |
