8
votes

I have a React Native, React hybrid app. For React Native i am using react-native-elements.

My app is run using Expo and was built out with the react-native init. I am getting the Material Icons (missing) RSD;

Material Icons missing

Through much searching, i have found the @expo/vector-icons but it doesn't seem to work. My App.js looks like this;

import React from 'react'
import { Font, AppLoading } from 'expo'
import { MaterialIcons } from '@expo/vector-icons'
import HybridApp from './src/App'

export default class NativeApp extends React.Component {
  constructor() {
    super()
    this.state = {
      fontsAreLoaded: false
    }
  }
  async componentWillMount() {
    await Font.loadAsync(MaterialIcons.font)
    this.setState({ fontsAreLoaded: true })
  }
  render() {
    const { fontsAreLoaded } = this.state
    return !fontsAreLoaded ? <AppLoading /> : <HybridApp />
  }
}

As you can see, i am waiting for the font to load... all to no avail.

4
In your app.json you don't happen to have 'json' included in your app.packagerOpts.assetExts: [] do you? If so then yeah, @expo/vector-icons won't work properly 😞 – Evan Bacon
see the complete answer here: Link – Rajnish singh

4 Answers

13
votes

After hours wracking my brain on this, the answer was there in front of me the whole time.

Presumably, React Native Elements refers to Material icons as Material Icons, not MaterialIcons.

This means that the default import from @expo/vector-icons does not work as their reference to Material icons is different.

The solution is to manually select Material icons from expo, replacing this line;

await Font.loadAsync(MaterialIcons.font)

with

await Font.loadAsync({
  'Material Icons': require('@expo/vector-icons/fonts/MaterialIcons.ttf')
})

I hope this saves someone some time in the future.

0
votes

The icons are actually fonts and must first be loaded. It seems they are autoloaded sometimes and others times are not.

So to ensure they are loaded, do this:

        import FontAwesome from './node_modules/@expo/vector-icons/fonts/FontAwesome.ttf';
        import MaterialIcons from './node_modules/@expo/vector-icons/fonts/MaterialIcons.ttf';
    ... 
      async componentWillMount() {
        try {
          await Font.loadAsync({
            FontAwesome,
            MaterialIcons
          });

          this.setState({ fontLoaded: true });
        } catch (error) {
          console.log('error loading icon fonts', error);
        }
      }
...
  render() {

    if (!this.state.fontLoaded) {

      return <AppLoading />;

    }

Then when you reference the type, it must be the same type that the component you are using is expecting.

For example, react native elements expects these types: material-community, font-awesome, octicon, ionicon, foundation, evilicon, simple-line-icon, zocial, or entypo

See complete answer here: http://javascriptrambling.blogspot.com/2018/03/expo-icon-fonts-with-react-native-and.html

0
votes

This question is old, but what worked for me and quite straightforward is

import { Ionicons } from "@expo/vector-icons";
await Font.loadAsync({...Ionicons.font, ...other imports })
0
votes

Check if you have any dependency warnings when you run the app. I had an expo-font version warning, when I fixed it this error went away.

Some dependencies are incompatible with the installed expo package version:
 - expo-font - expected version range: ~8.4.0 - actual version installed: ^9.1.0