React Native Using Expo not showing Icon correctly [ (X) and ? ]

12,903

Solution 1

You can’t use react-native-ionicons with Expo as the installation process requires you to update native code. https://github.com/fanqfanh/react-native-ionicons

However Expo comes bundled with Ionicons which can be used in the following way:

Add the following import statement at the top of your component

import { Ionicons } from '@expo/vector-icons';

Then use them like this

<Ionicons name="md-menu" size={32} color="green" />

You should also check the correct name to use here

https://expo.github.io/vector-icons/

this is because vector-icons can use different names from the original icon package that you are using.

For more information about the different icons that are in Expo see the documentation

https://docs.expo.io/versions/latest/guides/icons/

Here is a simple snack showing it working https://snack.expo.io/@andypandy/iconicons-example It shows the differences between icons for iOS and Android, and how to switch them based on the platform.

import * as React from 'react';
import { Text, View, StyleSheet, Platform } from 'react-native';
import { Constants } from 'expo';
import { Ionicons } from '@expo/vector-icons';


export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Ionicons name="md-menu" size={32} color="green" />
        <Ionicons name="ios-menu" size={32} color="red" />
        <Ionicons name={Platform.OS === 'ios' ? "ios-menu" : 'md-menu'} size={32} color="blue" />
        <Ionicons name="md-checkmark" size={32} color="green" />
        <Ionicons name="ios-checkmark" size={32} color="red" />
        <Ionicons name={Platform.OS === 'ios' ? "ios-checkmark" : 'md-checkmark'} size={32} color="blue" />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems:'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
});

Updates to the package.json

I've commented which dependencies I think you can safely get rid of from your package.json. These should not have been added as they either require access to native code or are already included in Expo.

"dependencies": {
  "@expo/vector-icons": "^9.0.0", // already included in expo
  "@material-ui/core": "^3.9.0",
  "@types/expo__vector-icons": "^6.2.3", // only required if you are using typescript, but I don't think you are using that
  "antd-mobile": "^2.2.6",
  "babel-plugin-import": "^1.11.0",
  "es6-symbol": "^3.1.1",
  "expo": "^32.0.0",
  "firebase": "^5.8.1",
  "haversine": "^1.1.0", 
  "moment": "^2.23.0",
  "moment-timezone": "^0.5.23",
  "native-base": "^2.8.1",
  "prop-types": "^15.6.2",
  "re-base": "^4.0.0",
  "react": "16.5.0",
  "react-dom": "^16.7.0",
  "react-moment": "^0.8.4",
  "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
  "react-native-audio": "^4.3.0", // can't be used in Expo as it requires native code
  "react-native-aws3": "0.0.8",
  "react-native-button": "^2.3.0",
  "react-native-elements": "^0.19.1",
  "react-native-emoji-selector": "^0.1.6",
  "react-native-fontawesome": "^6.0.1", // requires you to add the font yourself, also it is included in expo
  "react-native-gesture-handler": "^1.0.12", // already included in expo
  "react-native-gifted-chat": "^0.7.2",
  "react-native-gifted-messenger": "^0.1.4",
  "react-native-image-picker": "^0.28.0", // can't use this in expo as it requires native code
  "react-native-ionicons": "^4.4.6", // already included in expo, 
  "react-native-keyboard-aware-scroll-view": "^0.7.4",
  "react-native-linear-gradient": "^2.5.3", // can't be used in expo as it requires native code
  "react-native-maps": "^0.22.1", // already included in expo
  "react-native-navbar": "^2.1.0",
  "react-native-render-html": "^3.10.0",
  "react-native-router-flux": "^4.0.6",
  "react-native-sound": "^0.10.9", // cannot use this in expo as it requires native code
  "react-native-splash-screen": "^3.1.1", // cannot use this in expo as it requires native code
  "react-native-timeago": "^0.4.0",
  "react-native-vector-icons": "^6.2.0", // cannot use this in expo as it requires native code
  "react-navigation": "^3.0.7",
  "react-navigation-header-buttons": "^2.1.1",
  "react-simple-line-icons": "^1.0.8",
  "scheduler": "^0.11.3", // this is used internally by React, I don't think you require it here
  "tcomb-form-native": "^0.6.20"  
},

Solution 2

You must use

import { registerRootComponent } from 'expo';
import App from './App';

registerRootComponent(App);

instead of

import {AppRegistry} from 'react-native';
import App from './App';

AppRegistry.registerComponent('main', () => App);

to register your main component. Here is the solution in Expo https://github.com/expo/vector-icons/issues/89#issuecomment-475217923

Solution 3

In my case, I was getting the SQUARE X's due to a step required by react-native-svg-transformer. This was only a problem after I upgraded from SDK38 to SDK40.

For me, the workaround that worked was to remove the metro.config.js file that the transformer module requested I add. I'm not even sure if I was using the functionality that required this transformer anymore.. Removing it had no detrimental effect for me. It may have a detrimental effect for you, but it's worth a try to see if it fixes yours. I documented a bug here to alert the SVG Transformer team in case there's a fix required on their side.

https://github.com/kristerkari/react-native-svg-transformer/issues/128

So in summary the workaround is to remove metro.config.js (or remove the alterations made to metro.config.js if you had one before this module's changes), then "expo start -c" and try again..

Let me know if that helps anyone!

Share:
12,903
Alex Chong
Author by

Alex Chong

Updated on June 17, 2022

Comments

  • Alex Chong
    Alex Chong almost 2 years

    I have a problem of displaying the icon with my App. Whatever Icon I import, eg: From React native base, @expo/vector-icons, react-native-vector-icons/Ionicons ... etc.

    It will only show (X) or ?

    I tried out many method, including react-native link, using the default import icon from React-Native. It all doesn't work.

    Reference:

    1) https://ionicons.com/cheatsheet.html

    2) https://www.npmjs.com/package/react-native-ionicons

    I will attach my code and screenshot here, hope it help to solve my problem. Thank you.

    import Icon from 'react-native-ionicons'
    
    
            <ListItem style={styles.listitem_home} onPress={this.navigateToScreen('ExampleSendDataScreen')}>
              <Thumbnail square size={80} source={require('../../assets/images/message.png')}  style={{marginRight: 10}}/>
              <Body>
                <Text>{Strings.ST17}</Text>
                <Text numberOfLines={1} note style={styles.note_home}>{Strings.ST17}</Text>
              </Body>
              <Right>
                <Icon name="menu" style={styles.icon_home} />                
              </Right>
            </ListItem>
    

    Icon Styles

    icon_home:{
    
    fontSize: 20,
    color: 'black'
    },
    

    The only icon show in my app currently is Navigator Back Button. enter image description here

    enter image description here

    Edit 1: Installed @expo/vector-icons 9.0.0 enter image description here enter image description here

    Edit 2: Updated to Expo v32

    Package.json

    "dependencies": {
    "@expo/vector-icons": "^9.0.0",
    "@material-ui/core": "^3.9.0",
    "@types/expo__vector-icons": "^6.2.3",
    "antd-mobile": "^2.2.6",
    "babel-plugin-import": "^1.11.0",
    "es6-symbol": "^3.1.1",
    "expo": "^32.0.0",
    "firebase": "^5.8.1",
    "haversine": "^1.1.0",
    "moment": "^2.23.0",
    "moment-timezone": "^0.5.23",
    "native-base": "^2.8.1",
    "prop-types": "^15.6.2",
    "re-base": "^4.0.0",
    "react": "16.5.0",
    "react-dom": "^16.7.0",
    "react-moment": "^0.8.4",
    "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
    "react-native-audio": "^4.3.0",
    "react-native-aws3": "0.0.8",
    "react-native-button": "^2.3.0",
    "react-native-elements": "^0.19.1",
    "react-native-emoji-selector": "^0.1.6",
    "react-native-fontawesome": "^6.0.1",
    "react-native-gesture-handler": "^1.0.12",
    "react-native-gifted-chat": "^0.7.2",
    "react-native-gifted-messenger": "^0.1.4",
    "react-native-image-picker": "^0.28.0",
    "react-native-ionicons": "^4.4.6",
    "react-native-keyboard-aware-scroll-view": "^0.7.4",
    "react-native-linear-gradient": "^2.5.3",
    "react-native-maps": "^0.22.1",
    "react-native-navbar": "^2.1.0",
    "react-native-render-html": "^3.10.0",
    "react-native-router-flux": "^4.0.6",
    "react-native-sound": "^0.10.9",
    "react-native-splash-screen": "^3.1.1",
    "react-native-timeago": "^0.4.0",
    "react-native-vector-icons": "^6.2.0",
    "react-navigation": "^3.0.7",
    "react-navigation-header-buttons": "^2.1.1",
    "react-simple-line-icons": "^1.0.8",
    "scheduler": "^0.11.3",
    "tcomb-form-native": "^0.6.20"  },
    

    App.json

    "expo": {
    "name": "FirstTry",
    "description": "This project is really great.",
    "slug": "firsttry",
    "privacy": "public",
    "sdkVersion": "32.0.0",
    "platforms": ["ios", "android"],
    "version": "2.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "androidStatusBarColor": "#7bcbdb",
    "androidStatusBar": {
    "barStyle": "light-content",
    "backgroundColor": "#7bcbdb"
    },
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "bundleIdentifier": "com.firsttry",
      "supportsTablet": true
    },
    "android": {
      "package": "com.firsttry",
      "versionCode": 2
    
    }
    

    New ERROR. undefined is not an object (evaluating '_expo.default.Constant') on my ConfigApp.js

    enter image description here

    ConfigApp.js

    import Expo from 'expo';
    
    const isStandAloneApp = Expo.Constants.appOwnership == "standalone";
    
    const ConfigApp = {
    
    // backend url
    URL: "YOUR_BACKEND_URL",
    
    // banner admob unit id
    BANNER_ID: "YOUR_BANNER_ID",
    
    // interstitial admob unit id
    INTERSTITIAL_ID: "YOUR_INTERSTITIAL_ID",
    
    // testdevice id, DON'T CHANGE IT
    TESTDEVICE_ID : isStandAloneApp?"EMULATOR" : "EMULATOR"
    };
    
    export default ConfigApp;
    

    Edit 3: Unable to resolve "@expo/vector-icons" from "application\navigations\Logged.js"

    const leftIcon = (navigation, icon) => <Ionicons
    name={icon}
    style={{marginLeft: 20}}
    size={27}
    color="white"
    onPress={() => navigation.navigate('DrawerOpen')}
    />; 
    
      HomeScreen: {
    screen: HomeScreen,
    navigationOptions: ({navigation}) => ({
      headerLeft: leftIcon(navigation, "md-menu")
    })
    },
    

    Edit 4: Icon still not display correctly

    enter image description here

  • Samuel Liew
    Samuel Liew over 5 years
    Comments are not for extended discussion; this conversation has been moved to chat.
  • Cin88
    Cin88 almost 4 years
    I did this, and the solution from the answer below, and it still isn't working :(
  • bitcasual
    bitcasual about 2 years
    I get MaterialCommunityIcons' cannot be used as a JSX component whenever I try to insert it as a child.