'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