Molly Harper
Molly Harper

Reputation: 2453

Expo fonts in global stylesheet

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 {
  // ...
}

Upvotes: 3

Views: 5178

Answers (3)

tomekz
tomekz

Reputation: 366

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
        );
      }
    }

Upvotes: 0

ide
ide

Reputation: 20798

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.

Upvotes: 1

Molly Harper
Molly Harper

Reputation: 2453

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.

Upvotes: 0

Related Questions