3

I am using Expo and need to use custom fonts in my global stylesheet. Expo documents this, however it is not relevant in my case since componentDidMount() only executes within a class:

class App extends React.Component {
  componentDidMount() {
    Font.loadAsync({
      'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'),
    });
  }

  // ...
}

My global stylesheet looks like this:

const React = require('react-native');

import {
  Dimensions,
  StatusBar,
} from 'react-native';

const { StyleSheet } = React;

export default {
  // ...
}
ide
  • 19,942
  • 5
  • 64
  • 106
Molly Harper
  • 2,363
  • 3
  • 26
  • 35
  • I hit this error because the file in which I wrapped my app with a component that loaded my font was exporting the wrong component! – duhaime Oct 16 '19 at 22:56

3 Answers3

1

Font loading in Expo is "lazy" in the sense that you can create a StyleSheet object that references a font before it is loaded. For example, this code is valid:

async function exampleAsync() {
  let stylesheet = StyleSheet.create({
    fancyText: {
      ...Expo.Font.style('open-sans-bold'),
    },
  });

  await Expo.Font.loadAsync({
    'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'),
  });
}

So you don't need to call Expo.Font.loadAsync within componentDidMount necessarily, and it's OK to call StyleSheet.create and Expo.Font.style before the font is loaded.

What's important is that you wait for Expo.Font.loadAsync to complete before you render a component whose style uses the loaded font.

ide
  • 19,942
  • 5
  • 64
  • 106
0

I ended up just loading fonts within the Navigation file, and was then able to access these fonts in my global stylesheet and throughout my app.

Molly Harper
  • 2,363
  • 3
  • 26
  • 35
0

What you could do is simply in your root/top component add a state flag checking whether font async already finished.

Then add a condition in your render method to be sure that your child components will be rendered only after Fonts were succesfully loaded. Pls see example

     export default class App extends React.Component {
      state = {
        fontLoaded: false,
      }

      componentDidMount() {
        this.loadAssetsAsync();
      }

      async loadAssetsAsync() {
        await Expo.Font.loadAsync({
         'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf'),
        });;

        this.setState({ fontLoaded: true });
      }

      render() {
        if (!this.state.fontLoaded) {
          return <AppLoading />;  // render some progress indicator
        }

        return (
          <Navigator />    //render your child components tree
        );
      }
    }
tomekz
  • 266
  • 2
  • 4