How to use custom fonts in React-Native.
Tags: reactnative, react, javascript, tutorial
Published: 2021-05-31 11:29:58

Have you tried using font-family in react-native and it didn't seem to work? It's fine, you have nothing to worry about. The pattern used to render a font in CSS for the web is quite different from the way you will render it in a react-native app. LET'S DIVE IN!

To render a custom font in a react-native app, two main libraries are needed. These libraries are:

1. expo-font
2. expo-app-loading

##**expo-font**

expo-font is a library that allows one to load fonts from the web and use it in a react-native component. It does this with the help of a method called **loadAsync**. To use expo-font, we will need to install it with expo.

```javascript
expo install expo-font
```
##**expo-app-loading**

While the font from expo-font is still loading, expo-app-loading makes sure that a loading screen component or splash screen is running or being displayed. Once the font is loaded, it automatically allows the component with the font in it to display and allows the loading screen or splash screen to unmount. It does this with the help of a component called **Apploading**. We can use it by installing expo-app-loading with expo

```javascript
expo install expo-app-loading
```

The next thing to do is to download the fonts which you would want to use in your app and store them in the assets folder of your react-native app workspace. You can download google fonts at *https://fonts.google.com/* they have wonderful fonts over there.


##**Let's Build**

Firstly, we import our libraries :

```javascript
import React, { useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import * as Font from "expo-font";
import Apploading from "expo-app-loading";

```
*We import Apploading from expo-app-loading, which makes sure that the splash screen component or loading screen component is visible while it is mounted and we also import everything in expo-font as Font so as to load fonts.*

```javascript
const getFonts = () =>
  Font.loadAsync({
    limelight: require("./assets/fonts/Limelight/Limelight- 
    Regular.ttf"),
    indie: require("./assets/fonts/Indie_Flower/IndieFlower- 
    Regular.ttf"),
  });
```
We use loadAsync method to asynchronously load static or remote resources that can be used in the react-native application. In this case, we are using it to asynchronously load the required font needed in the react-native app. It registers the font in a name which will be used while referring to it with *fontFamily*.


```javascript
export default function App() {
  const [fontsloaded, setFontsLoaded] = useState(false);

  if (fontsloaded) {
    return (
     //you can return any component of your choice here
      <View style={styles.container}>
        <Text style={styles.Texts}>
          Open up App.js to start working on your app!
        </Text>
        <StatusBar style="auto" />
      </View>
    );
  } else {
    return (
      <Apploading
        startAsync={getFonts}
        onFinish={() => {
          setFontsLoaded(true);
        }}
        onError={console.warn}
      />
    );
  }
}
```
We use useState to monitor if the fonts is loaded or not and then we use the conditional statement to render a particular component depending depending on if the fonts is loaded or not. In the snippet above, if fonts is loaded(fontsloaded), then we return the component where the font is specified or else we return a component called Apploading. Apploading takes in three props which includes:
1. startAsync
2. onFinish
3. onError

**startAsync**
startAsync returns a promise. This promise is what is being loaded or resolved while the a loading screen or splash screen is mounted or running. In the case above, the getFont function is what is being called in startAsync.

**onFinish**
This guy takes in a function setFontLoaded and sets it to true. In the case above, the onFinish prop waits for startAsync to load the fonts from getFont function and then it updates the state of the react-native app thereby rendering the font being loaded.

**onError**
onError catches every possible error that might be thrown from startAsync and handles it properly.

Now, we can use our font in any component we wish to use it in.

```javascript
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  Texts: {
    fontFamily: "indie",
  },
});
```

As we can see above, the name of the font family is the specified name given to the font when loading it from loadAsync. We can now use the loaded font and also specify weight and other attributes to the font loaded.


Full code:

```javascript
import { StatusBar } from "expo-status-bar";
import React, { useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import * as Font from "expo-font";
import Apploading from "expo-app-loading";

const getFonts = () =>
  Font.loadAsync({
    limelight: require("./assets/fonts/Limelight/Limelight-Regular.ttf"),
    indie: require("./assets/fonts/Indie_Flower/IndieFlower-Regular.ttf"),
  });

export default function App() {
  const [fontsloaded, setFontsLoaded] = useState(false);

  if (fontsloaded) {
    return (
    //you can return any component of your choice here
      <View style={styles.container}>
        <Text style={styles.Texts}>
          Open up App.js to start working on your app!
        </Text>
        <StatusBar style="auto" />
      </View>
    );
  } else {
    return (
      <Apploading
        startAsync={getFonts}
        onFinish={() => {
          setFontsLoaded(true);
        }}
        onError={console.warn}
      />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  Texts: {
    fontFamily: "indie",
  },
});
```

With this little tutorial, I hope you are able to load a font properly in your react-native app. Go forth and be great!!