Search code examples
react-nativereact-native-vector-icons

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

  • 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