Augusto Batista
Augusto Batista

Reputation: 21

Undefined is not a function font.default error expo

So I have been trying to load custom fonts into abd expo managed project but everytime I get this function error...using async...useFonts you name it. This is my source code from my App.js.

import React, { useState } from "react";
import AppNavigator from "./src/navigator/AppNavigator";
import useFonts from "@use-expo/font";
import AppLoading from "expo";

const App = () => {
  const [isLoaded] = useFonts({
    "proxima-nova": require("./src/assets/fonts/proxima-nova.ttf"),
    "proxima-nova-bold": require("./src/assets/fonts/proxima-nova-bold.ttf"),
  });

  if (!isLoaded) {
    return <AppLoading />;
  } else {
    return <AppNavigator />;
  }
};

export default App;

enter image description here

Upvotes: 2

Views: 1711

Answers (1)

Chris Marshall
Chris Marshall

Reputation: 808

After quite a bit of playing around, I finally worked out what was wrong. So as long as you're using a functional component you could try something along these lines.

After (Working)

import React, { useState, useEffect} from 'react';
import { View, Text, StyleSheet, ActivityIndicator } from 'react-native';
import * as firebase from 'firebase';
import * as Font from 'expo-font';

export default function LoadingScreen({ navigation }) {
  const [fontsLoaded, setFontsLoaded] = useState(false);

  useEffect(() => {
    Font.loadAsync({
      'montserrat-bold': require('../assets/fonts/Montserrat-Bold.ttf'),
      'montserrat-light': require('../assets/fonts/Montserrat-Light.ttf'),
      'montserrat-regular': require('../assets/fonts/Montserrat-Regular.ttf'),
      'montserrat-thin': require('../assets/fonts/Montserrat-Thin.ttf'),
    }).then(() => setFontsLoaded(true));
  }, []);

  if (fontsLoaded) {
    firebase.auth().onAuthStateChanged(user => {
      navigation.navigate(user ? 'App' : 'Auth')
    })
  }

  return (
    <View style={styles.container}>
      <Text>Loading...</Text>
      <ActivityIndicator size="large"></ActivityIndicator>
    </View>
  );
}

Before (Not Working)

import React, { useState, useFont} from 'react';
import { View, Text, StyleSheet, ActivityIndicator } from 'react-native';
import * as firebase from 'firebase';
import * as Font from 'expo-font';

export default function LoadingScreen() {
  let [fontsLoaded] = Font.useFonts({
    'montserrat-bold': require('../assets/fonts/Montserrat-Bold.ttf'),
    'montserrat-light': require('../assets/fonts/Montserrat-Light.ttf'),
    'montserrat-regular': require('../assets/fonts/Montserrat-Regular.ttf'),
    'montserrat-thin': require('../assets/fonts/Montserrat-Thin.ttf'),
  });

  if (!fontsLoaded) {
    return (
      <View style={styles.container}>
        <Text>Loading...</Text>
        <ActivityIndicator size="large"></ActivityIndicator>
      </View>
    );
  }

  if (fontsLoaded) {
    firebase.auth().onAuthStateChanged(user => {
      this.props.navigation.navigate(user ? 'App' : 'Auth')
    })
  }
}

Basically have a loader or something like the ActivityIndicator on the route that's waiting for a state update and after Font.loadFonts load it will hit the if statement and you could probably just return the app navigator. The reason I'm not is due to my authentication flow with firebase.

Upvotes: 1

Related Questions