25

I'm getting the error: You started loading 'Roboto_medium', but used it before it finished loading when using native base.

enter image description here

I've followed the instructions in the official page.

To create react native app I'm using create-react-native-app.

App.js

export default class App extends React.Component {

async componentWillMount() {
  await Expo.Font.loadAsync({
  'Roboto': require('native-base/Fonts/Roboto.ttf'),
  'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
  'Ionicons': require('@expo/vector-icons/fonts/Ionicons.ttf'),
 });
}

 render() {
   return (
    <Container>
      <StatusBar hidden={true} />

    <Button>
      <Text>
        Button
      </Text>
    </Button>

    <ListaItens />
    </Container>
  );
}
} 
Igor Martins
  • 2,015
  • 7
  • 36
  • 57

6 Answers6

51

you need to wait till the fonts get loaded. You can do something like this

import React from "react";
import { StatusBar } from "react-native";
import { Container, Button, text, ListItem, Text } from "native-base";
import Expo from "expo";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { loading: true };
  }

  async componentWillMount() {
    await Expo.Font.loadAsync({
      Roboto: require("native-base/Fonts/Roboto.ttf"),
      Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
      Ionicons: require("@expo/vector-icons/fonts/Ionicons.ttf"),
    });
    this.setState({ loading: false });
  }

  render() {
    if (this.state.loading) {
      return <Expo.AppLoading />;
    }
    return (
      <Container>
        <StatusBar hidden={true} />

        <Button>
          <Text>Button</Text>
        </Button>

        <ListItem />
      </Container>
    );
  }
}
akhil xavier
  • 1,847
  • 15
  • 15
4

This new code for expo SDK 35 which was modified from @akhil xavier 's answer

First install expo-font

expo install 'expo-font'

here is the App.js

import React from "react";
import * as Font from "expo-font";
import { ActivityIndicator } from "react-native";
import { Root } from "native-base";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { loading: true };
  }

  async componentWillMount() {
    await Font.loadAsync({
      Roboto: require("native-base/Fonts/Roboto.ttf"),
      Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
      Ionicons: require("@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Ionicons.ttf"),
    });
    this.setState({ loading: false });
  }

  render() {
    if (this.state.loading) {
      return <ActivityIndicator />;
    }
    return (
      <Root>
       <RootPage /> // starter component (i.e. nav)
      </Root>
    );
  }
}
fmchan
  • 760
  • 1
  • 11
  • 29
4

The solution that works for me is below. The error I had was that I imported Font as (Fonts) but while calling it failed to notice the 's'. Fixed it by making sure the import name is similar to what you call the loadAsync to. You need to have 'expo-font' installed in your project for it to work

import React from "react";
import * as Font from "expo-font";
import { AppLoading } from "expo";
import MealsNavigator from "./navigation/MealsNavigator";


const fetchFonts = () => {
  return Font.loadAsync({
    "open-sans": require("./assets/fonts/OpenSans-Regular.ttf"),
    "open-sans-bold": require("./assets/fonts/OpenSans-Bold.ttf")
  });
};

export default function App() {
  const [fontLoaded, setFontLoaded] = useState(false);
  if (!fontLoaded) {
    return (
      <AppLoading
        startAsync={fetchFonts}
        onFinish={() => setFontLoaded(true)}
        onError={err => console.log(err)}
      />
    );
  }
  return <MealsNavigator />;
}
cherucole
  • 560
  • 7
  • 15
  • 1
    Nice. Glad to see someone else is also following Max's courses. In my case I forgot to return Font.loadAsync() inside of fetchFonts. – Gustavo Maximo Jan 06 '21 at 23:59
3

If anyone is having this issue with the 'MaterialIcons' font family, I had a similar problem and found following this solution worked:

https://javascriptrambling.blogspot.com.au/2018/03/expo-icon-fonts-with-react-native-and.html

You basically need to:

  1. Install the fonts (using npm install)
  2. Do a Font.loadAsync on the fonts in your componentWillMount() function.
  3. Remember to mark the componentWillMount() function as async
  4. The conditionally display either as 'loading' or with the view depending on the state of a 'loaded' flag.

For example:

import React from 'react';
import { View } from 'react-native';
import { Avatar } from 'react-native-elements';
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';


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>
    );
  }
}
Andre DiCioccio
  • 1,191
  • 1
  • 8
  • 10
0

This is the way which I use to load Fonts in my project. I feel this more abstracted as compared to all the other answers.

What you need to do is create a custom hook to Load fonts

You can do it something like this

Create a folder called hooks where your App.js is located. Then inside hooks folder create a file called useFonts.js

Inside useFonts.js write like this

import * as Font from 'expo-font';

export default useFonts = async () =>
  await Font.loadAsync({
    Roboto: require('native-base/Fonts/Roboto.ttf'),
    Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
    Ionicons: require('@expo/vector-icons/fonts/Ionicons.ttf'),
  });

Now in your App.js write like this

import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import React, { useState } from 'react';

import useFonts from './hooks/useFonts';

export default function App() {
  const [IsReady, SetIsReady] = useState(false);

  // This function will start the fontLoading
  const LoadFonts = async () => {
    await useFonts();
  };

  // This is a check to ensure fonts get loaded
  if (!IsReady) {
    return (
      <AppLoading
        startAsync={LoadFonts}
        onFinish={() => SetIsReady(true)}
        onError={() => {}}
      />
    );
  }

  // If fonts are successfully loaded then show the rest of your App
  return (
    <Container>
      <StatusBar hidden={true} />

      <Button>
        <Text>Button</Text>
      </Button>

      <ListaItens />
    </Container>
  );
}
Kartikey
  • 4,516
  • 4
  • 15
  • 40
-5

One reason why it has to load font is because you are using the Native Base Text component. If you import the React Native Text component instead you won't even have to load fonts and you won't see that error.

Tawanda Muzavazi
  • 405
  • 3
  • 14
  • no, it's not true. i don't have error when importing Text from native base. The error occurs once I use Card – fmchan Oct 05 '19 at 07:47