fontFamily 'MaterialIcons' is not a system font and has not been loaded through Expo.Font.loadAsync. - If you intended to use a system font, make sure you typed the name correctly and that it is supported by your device operating system. - If this is a custom font, be sure to load it with Expo.Font.loadAsync.
It was driving me nuts. Googling for the answer just brought up snippets of information about what to do. So finally I pieced together the parts to get it working.
You have to load the fonts before they are used. It seems that if you ever blow away your node_modules and then do npm install again, you lose the built in loading. So you have to do it manually. Here is how!
I made sure the @expo/vector icons are loaded:
npm install --save @expo/vector-icons
Then I changed the App to load them directly:
import React from 'react';
import { View } from 'react-native';
import { Avatar } from 'react-native-elements';
import FontAwesome
from './node_modules/@expo/vector-icons/fonts/FontAwesome.ttf';
import MaterialIcons
from './node_modules/@expo/vector-icons/fonts/MaterialIcons.ttf';
export default class App extends React.Component {
}
state = {
fontLoaded: false
};
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 />;
}
return (
<View>
<Text>My App</Text>
<Avatar
small
rounded
icon={{ name: 'add' }}
/>
</View>
);
}
So now the fonts load before the app is shown. While they are loading, the AppLoading continues to render the loading screen before showing any of the app. The fonts get loaded, then the state is set so the AppLoading component no longer renders and it continues to your app.
But why throw all that into the main App.js? It's messy. So I made an AppFontLoader utility that looks like this:
import React from 'react';
import { AppLoading, Font } from 'expo';
import FontAwesome
from '../../node_modules/@expo/vector-icons/fonts/FontAwesome.ttf';
import MaterialIcons
from '../../node_modules/@expo/vector-icons/fonts/MaterialIcons.ttf';
class AppFontLoader extends React.Component {
state = {
fontLoaded: false
};
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 />;
}
return this.props.children;
}
}
export { AppFontLoader };
Now the App.js gets simplified!
import React from 'react';
import { View } from 'react-native';
import { Avatar } from 'react-native-elements';
export default class App extends React.Component { render() {
<View>
);
}
return (
<AppFontLoader>
<Text>My App</Text>
<Avatar
small
rounded
icon={{ name: 'add' }}
/>
</View>
</AppFontLoader>
}
I hope this helps you. It shouldn't take 4 hours to figure this out!
hey there. Thanks for sharing.
ReplyDeleteI am wondering, is it the right solution to fix? i can run the app without any problem in ios expo but android is giving this error? is it something to do with android itself?
I don't have experience with IOS yet but many cases seem to cause this error (at least in Android). This code ensures the fonts get loaded before you try and use them.
ReplyDeleteHello, I've used this method but ran into some issues I've got the following
ReplyDeletethis.setState({fontLoaded:true});
console.log('fonts are now loaded');
} catch (error) {
console.log(error);
}
Console is returning fonts are now loaded, no errors. Just stuck on white AppLoading screen. Any ideas?
From you code... return this.props.children;
DeleteReplace 'this.props.children;' with the main router in my case ; and all is working!!!
Thank you!
It worked for me! Thanks a lot! I dont have much experience in react native and you solution saved my life
ReplyDeleteawesome thanks I was dying because of it.
ReplyDeletethanks.. worked
ReplyDeletefor me
Nice, thanks for this. This error was killing me
ReplyDeleteI have copied the code completley but when I use the component I am getting this error: Export 'AppFontLoader' is not defined.
ReplyDeleteMy problem was in SimpleLineIcons. I added this code and it worked.
ReplyDeleteawait Expo.Font.loadAsync({
SimpleLineIcons: require("native-base/Fonts/SimpleLineIcons.ttf")
});
You saved me ! Thanks !
ReplyDelete