I am trying To make a custom hook that loads fonts using {useFonts} from expo, so that i wont have to repeat the code evrytime, and here is what I got so far.
import { useFonts } from "expo-font";
export default useAppFonts = () => {
const [loaded] = useFonts({
RobotoSlabBlack: require("../Fonts/RobotoSlab-Black.ttf"),
RobotoSlabBold: require("../Fonts/RobotoSlab-Bold.ttf"),
RobotoSlabExtraBold: require("../Fonts/RobotoSlab-ExtraBold.ttf"),
RobotoSlabExtraLight: require("../Fonts/RobotoSlab-ExtraLight.ttf"),
RobotoSlabThin: require("../Fonts/RobotoSlab-Thin.ttf"),
RobotoSlabRegular: require("../Fonts/RobotoSlab-Regular.ttf"),
});
return loaded;
};
the problem is that it works the first time I load the app but when I reload it stops working and the text reverts back to default fonts.
making a custom text component with the fonts already it came to mind, but it really bothers me that I can't do it like this.
and if its not possible I would like to know that, thank you for anyone with a response.
Use loadAsync instead of useFonts
To loadFonts which I do in all my project is create a folder called hooks where your App.js is located
Then, Install expo-app-loading & expo-font
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({
"Montserrat-Bold": require("../assets/fonts/Montserrat-Bold.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);
const LoadFonts = async () => {
await useFonts();
};
if (!IsReady) {
return (
<AppLoading
startAsync={LoadFonts}
onFinish={() => SetIsReady(true)}
onError={() => {}}
/>
);
}
return <View styles={styles.container}>{/* Your App Code Here */}</View>;
}
Related
My code is as follows:
import { StatusBar } from 'expo-status-bar';
import Home from './screens/home';
import * as Font from 'expo-font';
import React, { useState } from 'react';
import { AppLoading } from 'expo-app-loading';
const getFonts = () => Font.loadAsync({
'montserrat-regular': require('./assets/fonts/Montserrat-Regular.ttf'),
'montserrat-medium': require('./assets/fonts/Montserrat-Medium.ttf'),
'wreath': require('./assets/fonts/insigne - Wreath Halftone Medium.otf'),
});
export default function App() {
const [fontsLoaded, setFontsLoaded] = useState(false);
if(fontsLoaded)
{
return (
<Home />
);
} else{
return(
<AppLoading
startAsync = {getFonts}
onFinish={() => setFontsLoaded(true)}
/>
)
}
}
and this is showing the following error:
Render Error
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of 'App'.
The fonts should work as I am learning but it's throwing an error while working propoerly if I remove the fonts
It might be because of your getFonts is not async function. Try making it async like below:
const getFonts = async () => await Font.loadAsync({
'montserrat-regular': require('./assets/fonts/Montserrat-Regular.ttf'),
'montserrat-medium': require('./assets/fonts/Montserrat-Medium.ttf'),
'wreath': require('./assets/fonts/insigne - Wreath Halftone Medium.otf'),
});
Im using react native#0.70.5 with expo#~47.0.8
Im trying to use custom fonts and whenever I import them using expo font I get this error: Unable to resolve "../../assets/fonts/Montserrat-Regular.tff" from "core\hooks\useFonts.js"
here is my react-native.config.js file:
module.exports = {
project: {
ios: {},
android: {},
},
assets: ["./assets/fonts/"],
};
here's the use font hook
import * as Font from "expo-font";
export default useFonts = async () =>
await Font.loadAsync({
"Montserrat-Regular": require("../../assets/fonts/Montserrat-Regular.tff"),
});
and here's the app.js:
import { View } from "react-native";
import AppLoading from "expo-app-loading";
import MainNavigator from "./core/navigation/main";
import useFonts from "./core/hooks/useFonts";
export default function App() {
const [IsReady, SetIsReady] = useState(false);
const LoadFonts = async () => {
await useFonts();
};
if (!IsReady) {
return (
<AppLoading
startAsync={LoadFonts}
onFinish={() => SetIsReady(true)}
onError={() => {}}
/>
);
}
return (
<View>
<MainNavigator></MainNavigator>;
</View>
);
}
I've tried moving the useFont hook directly to App.js and it still can't resolve the font file. Take note, the path file is absolutely accurate.
edit:
Here is my folder structure
ROOT
App.js
react-native.config.js
core
--hooks
----useFonts.js
assets
--fonts
----Montserrat-Regular.ttf
I am new to using react native. I am using the code contributed in other topics similar to this one:
I use a hook:
import * as Font from "expo-font";
export default useFonts = async () =>
await Font.loadAsync({
Bebas: require('../assets/fonts/BebasNeue-Regular.ttf'),
Montserrat: require('../assets/fonts/Montserrat-Italic-VariableFont_wght.ttf'),
Inter: require('../assets/fonts/Inter-Black.otf')
});
And then in my app.js:
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);
const LoadFonts = async () => {
await useFonts();
};
if (!IsReady) {
return (
<AppLoading
startAsync={LoadFonts}
onFinish={() => SetIsReady(true)}
onError={() => {}}
/>
);
}
return <View styles={styles.container}>{/* Code Here */}</View>;
}
I then try to use them with the same name in my different screens, and I think they are loaded correctly, (no error), but I can't see the change when I restart my application.
I'm using expo-cli, can somebody help me in using custom fonts for Expo Managed React Native projects.
Image Link
Install expo-font
expo install expo-font
Then install expo-app-loading
expo install expo-app-loading
Create a folder called hooks where your App.js is located.
Inside hooks folder create a file called useFonts.js paste this code
useFonts.js
import * as Font from 'expo-font';
const useFonts = async () => {
await Font.loadAsync({
Fontello: require('../assets/fonts/fontello.ttf'),
// Place your custom fonts here and make sure that their location is set properly
});
};
export default useFonts;
Then in your App.js paste this code
import React, { useState } from 'react';
import AppLoading from 'expo-app-loading';
import useFonts from './hooks/useFonts';
export default function App() {
const [IsReady, setIsReady] = useState(false);
const LoadFonts = async () => {
await useFonts();
};
if (!IsReady) {
return (
<AppLoading
startAsync={LoadFonts}
onFinish={() => setIsReady(true)}
onError={(error) => console.log(error)}
/>
);
}
return (
<View>
// Your App Content here
</View
);
}
Working Example
I'm trying to load a fontello icons in my project, but if I try to load in App.js, it send "false' and the app don't load:
import React, {useState} from "react";
import AppLoading from "expo-app-loading";
import { ThemeProvider } from "styled-components";
import theme from "./src/globalStyles/theme";
import Routes from "./src/routes";
import {
useFonts,
Roboto_400Regular,
Roboto_500Medium,
Roboto_700Bold,
} from "#expo-google-fonts/roboto";
import { Fontello } from "./assets/fonts/fontello.ttf";
export default function App() {
const [fontsLoaded] = useFonts({
Roboto_400Regular,
Roboto_500Medium,
Roboto_700Bold,
Fontello,
});
console.log(fontsLoaded)
if (!fontsLoaded) {
return <AppLoading />;
}
return (
<ThemeProvider theme={theme}>
<Routes />
</ThemeProvider>
);
}
And if I comment the line with Fontello, it load the app but I got the following error:
fontFamily "fontello" is not a system font and has not been loaded through Font.loadAsync.
If you intended to use a system font, make sure you typed the name correctly and that it is supported by your device operating system.
If this is a custom font, be sure to load it with Font.loadAsync.
Install expo-font
expo install expo-font
Create a folder called hooks where you App.js is located.
Inside hooks folder create a file called useFonts.js paste this code
useFonts.js
import * as Font from 'expo-font';
import { Roboto_400Regular } from '#expo-google-fonts/roboto';
const useFonts = async () => {
await Font.loadAsync({
Roboto: Roboto_400Regular,
Fontello: require('../assets/fonts/fontello.ttf'),
// All Other Fonts
});
};
export default useFonts;
Then in your App.js paste this code
import React, { useState } from 'react';
import AppLoading from 'expo-app-loading';
import { ThemeProvider } from 'styled-components';
import theme from './src/globalStyles/theme';
import Routes from './src/routes';
import useFonts from './hooks/useFonts';
export default function App() {
const [IsReady, setIsReady] = useState(false);
const LoadFonts = async () => {
await useFonts();
};
if (!IsReady) {
return (
<AppLoading
startAsync={LoadFonts}
onFinish={() => setIsReady(true)}
onError={(error) => console.log(error)}
/>
);
}
return (
<ThemeProvider theme={theme}>
<Routes />
</ThemeProvider>
);
}
Working Example Works on Android. Some bug in the web version.