React Native Expo: Custom Fonts Not Loading Along With Google Fonts - javascript

I'm trying to load downloaded fonts along with google fonts using Font.loadAsync but it is giving me error:
Unable to resolve module ../../assets/fonts/sf-ui-text/SFUIText-Bold.ttf from /Users/bilal/Work/datumbrain/erp-app/src/utils/useFonts.js:
None of these files exist:
* SFUIText-Bold.ttf
* assets/fonts/sf-ui-text/SFUIText-Bold.ttf/index(.native|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx|.android.js|.native.js|.js|.android.jsx|.native.jsx|.jsx|.android.json|.native.json|.json|.android.svg|.native.svg|.svg)
Here is my code in App.js:
import { useCallback, useEffect, useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Provider } from 'react-redux';
import colors from './src/constants/colors';
import AppNavigator from './src/navigation/AppNavigator';
import { store } from './src/redux/store';
import * as SplashScreen from 'expo-splash-screen';
import * as Font from 'expo-font';
import {
FiraSans_300Light,
FiraSans_400Regular,
FiraSans_500Medium,
} from '#expo-google-fonts/fira-sans';
import { useFonts } from './src/utils/useFonts';
const App = () => {
const [appIsReady, setAppIsReady] = useState(false);
const prepare = async () => {
try {
const customFonts = await useFonts();
await SplashScreen.preventAutoHideAsync();
await Font.loadAsync({
'Fira Sans 300': FiraSans_300Light,
'Fira Sans 400': FiraSans_400Regular,
'Fira Sans 500': FiraSans_500Medium,
...customFonts,
});
} catch (e) {
console.warn(e);
} finally {
setAppIsReady(true);
console.log('Loaded fonts...');
}
};
const onLayoutRootView = useCallback(async () => {
if (appIsReady) {
await SplashScreen.hideAsync();
}
}, [appIsReady]);
useEffect(() => {
prepare();
}, []);
useEffect(() => {
onLayoutRootView();
}, [onLayoutRootView]);
if (!appIsReady) {
return null;
}
return (
<Provider store={store} style={styles.container}>
<AppNavigator />
</Provider>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: colors.light,
alignItems: 'center',
justifyContent: 'center',
},
});
export default App;
and useFonts.js:
import * as Font from 'expo-font';
export const useFonts = async () => {
await Font.loadAsync({
SF: require('../../assets/fonts/sf-ui-text/SFUIText-Bold.ttf'),
});
};

Please make sure the path here is correct
SF: require('../../assets/fonts/sf-ui-text/SFUIText-Bold.ttf')
For the Font.loadAsync, it looks perfect to me. For extra, you could use useFont hook to make your handling looks better. (It uses Font.loadAsync underneath)

Сheck the file path, this error occurs when the path is invalid.
Your useFonts function doesn't return anything, so you don't need spread in prepare(). If it is called fonts will be loaded anyway.

Related

Why my app is only showing loading screen? and warn me TypeError: undefined is not an object (evaluating '_asyncStorage.AsyncStorage.getItem')

Why my app is only showing loading screen? when i am running my app than its only loading and not showing other screens and showing a WARN that
` WARN Possible Unhandled Promise Rejection (id: 0): TypeError: undefined is
i think it has problem with this code
import React, { useEffect } from 'react';
import { View, ActivityIndicator, StyleSheet} from 'react-native';
import { AsyncStorage } from '#react-native-async-storage/async-storage';
import { useDispatch } from 'react-redux';
import Colors from '../constants/Colors';
import * as authActions from '../store/actions/auth';
const StartupScreen = props => {
const dispatch = useDispatch();
useEffect(() => {
const tryLogin = async () => {
const userData = await AsyncStorage.getItem('userData');
if (!userData) {
// props.navigation.navigate('Auth');
dispatch(authActions.setDidTryAutoLogin());
return;
}
const transformedData = JSON.parse(userData);
const { token, user } = transformedData;
// props.navigation.navigate('Shop');
dispatch(authActions.authenticate(user, token));
};
tryLogin();
}, [dispatch])
return (
<View style={styles.screen}>
<ActivityIndicator size="large" color={Colors.primary} />
</View>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
export default StartupScreen;
According to the docs you import is wrong.
This:
import { AsyncStorage } from '#react-native-async-storage/async-storage';
should be
import AsyncStorage from '#react-native-async-storage/async-storage';
Basically, what you are trying to do with {AsyncStorage} is you are importing "part" of the exported code called AsyncStorage. That is why the error says:
_asyncStorage.AsyncStorage.getItem') (asyncStorage mentioned twice) and you need the entire object out of the package.

React Native Expo - Custom Fonts Not Loading With Font.loadAsync

I'm up to date on the latest Expo version but for some reason, I can not get a simple custom font going. Here is a fresh project I set up attempting to get a custom font installed.
import React, { useState } from 'react';
import { Text, View } from 'react-native';
import AppLoading from 'expo-app-loading';
import * as Font from 'expo-font';
const fetchFonts = () =>
Font.loadAsync({
'Inter-Black': require('./assets/fonts/Inter-Black.otf'),
});
export default (props) => {
const [dataLoaded, setDataLoaded] = useState(false);
if (!dataLoaded) {
return (
<AppLoading
startAsync={fetchFonts}
onFinish={() => setDataLoaded(true)}
onError={(err) => console.log(err)}
/>
);
}
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ fontFamily: 'Inter-Black', fontSize: 40 }}>
Inter Black
</Text>
<Text style={{ fontSize: 40 }}>Platform Default</Text>
</View>
);
};
This is what I get in the console:
fontFamily "Inter-Black" 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.
at node_modules/expo-font/build/Font.js:27:16 in processFontFamily
at [native code]:null in performSyncWorkOnRoot
at [native code]:null in dispatchAction
at App.js:19:37 in AppLoading.props.onFinish
at node_modules/expo-app-loading/build/AppLoading.js:41:12 in startLoadingAppResourcesAsync
at [native code]:null in flushedQueue
at [native code]:null in invokeCallbackAndReturnFlushedQueue
You have to await the loading fucntion
const fetchFonts = async () =>
await Font.loadAsync({
'Inter-Black': require('./assets/fonts/Inter-Black.otf'),
});
Also, instead of this, try creating a custom hook to Load fonts. Check this answer.
You can do it somenthing 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({
'Inter-Black': require('./assets/fonts/Inter-Black.otf'),
});
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}>{/* Code Here */}</View>;
}
Add font resource to project folder exp assets/fonts
create variable fonts exp customFonts
Import on App.js like this
import AppLoading from 'expo-app-loading';
import { useFonts } from 'expo-font';
let customFonts = {
'Poppins-Black': require('./assets/fonts/Poppins-Black.ttf')
};
const App = () => {
const [isLoaded] = useFonts(customFonts);
if (!isLoaded) {
return <AppLoading />;
}
return <RootApp />;
}

Call function on application load in React Native

I have a React Native application and it has tabbed layout. I need to call some function when the main screen is loaded. I tried to use componentWillMount() function, but it didn't work because my screen was defined in function and not in class. How can I create on load function?
HomeScreen.js
import React, { useState, Component } from 'react';
import { View, Text } from 'react-native';
import { getText } from '..components/getText';
export default function HomeScreen() {
const [onLoadText, setText] = useState("");
const onScreenLoad = () => {
setText(getText());
}
const componentWillMount = () => {
// Not working
onScreenLoad();
}
return (
<View style={styles.container}>
<Text>{onLoadText}</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});
since you're using a stateless component, you can use the useEffect hook
useEffect(() => {
// write your code here, it's like componentWillMount
}, [])
You must add useEffect
import React, { useState, Component, useEffect } from 'react';
import { View, Text } from 'react-native';
import { getText } from '..components/getText';
export default function HomeScreen() {
const [onLoadText, setText] = useState("");
const onScreenLoad = () => {
setText(getText());
}
useEffect(() => {
// write your code here, it's like componentWillMount
onScreenLoad();
}, [])
return (
<View style={styles.container}>
<Text>{onLoadText}</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});

Font is not loading on either IOS or Android

It says I can use Expo.Apploading but I have no idea about that. If someone could help it would be great. This happens in either of device I am running. Below is code for App.js
import React, {useState}from 'react';
import {Text, View } from 'react-native';
import *as Font from 'expo-font';
import {AppLoading} from 'expo';
import {enableScreens} from 'react-native-screens';
import EstesGuideNavigator from './navigation/EstesGuideNavigator';
enableScreens(); // useScreens has been changed to enableScreens - this helps screens load faster in background
const fetchFonts = () => { //fetching costum fonts for my app using Async
Font.loadAsync({
'raleway-blackItalic' : require('./assets/fonts/Raleway-BlackItalic.ttf'),
'raleway-bold' : require('./assets/fonts/Raleway-Bold.ttf'),
'raleway-regular' : require('./assets/fonts/Raleway-Regular.ttf'),
'raleway-thin' : require('./assets/fonts/Raleway-Thin.ttf')
});
};
export default function App() {
const [fontLoaded, setFontLoaded] = useState(false); //initially it's false because app hasn't been loaded
if (!fontLoaded) {
return(
<AppLoading
startAsync = {fetchFonts}
onFinish = {() => setFontLoaded(true) }
/> //if assets(fonts here) is not loaded we display loading screen and load assets for app
);
}
return <EstesGuideNavigator/>;
}
Is there any way to resolve this?
I don't know what's wrong but this is how i handle my font loading, Works perfectly
import { AppLoading } from "expo";
import { Asset } from "expo-asset";
import * as Font from "expo-font";
import React, { useState } from "react";
import { Platform, StatusBar, StyleSheet, View } from "react-native";
import { Ionicons } from "#expo/vector-icons";
import AppNavigator from "./navigation/AppNavigator";
export default function App(props) {
const [isLoadingComplete, setLoadingComplete] = useState(false);
if (!isLoadingComplete && !props.skipLoadingScreen) {
return (
<AppLoading
startAsync={loadResourcesAsync}
onError={handleLoadingError}
onFinish={() => handleFinishLoading(setLoadingComplete)}
/>
);
} else {
return (
<View style={styles.container}>
{Platform.OS === "ios" && <StatusBar barStyle="default" />}
<AppNavigator />
</View>
);
}
}
async function loadResourcesAsync() {
await Promise.all([
Asset.loadAsync([
require("./assets/images/tick.png"),
require("./assets/images/error.png")
]),
Font.loadAsync({
// This is the font that we are using for our tab bar
...Ionicons.font,
// We include SpaceMono because we use it in HomeScreen.js. Feel free to
// remove this if you are not using it in your app
"space-mono": require("./assets/fonts/SpaceMono-Regular.ttf"),
"Gilroy-Bold": require("./assets/fonts/Gilroy-Bold.otf"),
"Gilroy-Medium": require("./assets/fonts/Gilroy-Medium.otf"),
"Gilroy-Heavy": require("./assets/fonts/Gilroy-Heavy.otf")
})
]);
}
function handleLoadingError(error) {
// In this case, you might want to report the error to your error reporting
// service, for example Sentry
console.warn(error);
}
function handleFinishLoading(setLoadingComplete) {
setLoadingComplete(true);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff"
}
});

problem with hook for react-native async function

I try to load a fontfamily, I used hook with async function but I have some errors:
function Button(props: TouchableOpacityProps & ButtonProps) {
useEffect(() => {
async function loadFont() {
await Font.loadAsync({
gotham_medium: require("../../assets/GothamMedium_1.ttf")
});
}
loadFont()
}, []);
return (
<TouchableOpacity {...props} style={styles.button}>
<Text style={styles.title}>{props.title}</Text>
</TouchableOpacity>
);
};
I imported Font from expo and useEffect from react but I have this error.
error on the device
This is what I have on my app in case it may help someone.
useEffect(() => {
const loadFonts = async () => {
await Font.loadAsync({
'pokeh': require('../../assets/fonts/pokeh.ttf'),
});
setFontReady(true);
};
loadFonts();
}, []);
And these two on the top after installing expo-font with npm
import * as Font from 'expo-font';
import { AppLoading } from 'expo';
Under this tree structure:
Your error might be generated by the wrong React version. Are you sure you're using at least Expo SDK 33?
If that's not the issue, I believe it might be easier if you load all assets earlier in the process. Expo provides an AppLoading component that takes a startAsync prop, which can be used to resolve all async promises pretty easily.
So your App.js could look like:
import { AppLoading } from 'expo';
import * as Font from 'expo-font';
import React, { useState } from 'react';
import { StyleSheet, View, Text } from 'react-native';
export default function App(props) {
const [isLoadingComplete, setLoadingComplete] = useState(false);
if (!isLoadingComplete && !props.skipLoadingScreen) {
return (
<AppLoading
startAsync={loadResourcesAsync}
onError={handleLoadingError}
onFinish={() => handleFinishLoading(setLoadingComplete)}
/>
);
} else {
return (
<View style={styles.container}>
<Text style={styles.title}>Welcome to your Expo app</Text>
</View>
);
}
}
async function loadResourcesAsync() {
await Promise.all([
Font.loadAsync({
'gotham-medium': require('./assets/GothamMedium_1.ttf')
}),
]);
}
function handleLoadingError(error) {
console.warn(error);
}
function handleFinishLoading(setLoadingComplete) {
setLoadingComplete(true);
}
const styles = StyleSheet.create({
container: {
marginTop: 60,
flex: 1,
backgroundColor: '#fff',
},
title: {
fontFamily: 'gotham-medium',
fontSize: 36
}
});
and then you have access to fontFamily: 'gotham-medium' anywhere in your app. Also you can resolve multiple promises (load other assets, etc.) within the Promise.all() call.
Let me know if that helped. Cheers!

Categories

Resources