Reputation: 91
I'm trying to use a font (google fonts) in a react native app. I'm having a problem with the hook:
const [fontsLoaded ,setFontsLoaded] = useState(false);
I believe the problem is around the render() prop. Can anyone advise me on where I should add the above code to get this woking?
My Code is:
import React, { Component, useState } from 'react';
import * as Font from 'expo-font';
import { StyleSheet, Text, View } from 'react-native';
import { AppLoading } from 'expo';
const getFonts = () => Font.loadAsync({
'lobster': require('./assets/fonts/Lobster-Regular.ttf')
});
export default class App extends Component {
render() {
const [fontsLoaded ,setFontsLoaded] = useState(false);
const gradientHeight=500;
const gradientBackground = '#12C1E5';
const data = Array.from({ length: gradientHeight });
if(fontsLoaded){
return (
<View style={styles.container}>
<View style={styles.centering}>
<Text style={styles.titleText}>Test Title</Text>
</View>
<View style={{flex:1}}>
{data.map((_, i) => (
<View
key={i}
style={{
position: 'absolute',
backgroundColor: gradientBackground,
height: 1,
bottom: (gradientHeight - i),
right: 0,
left: 0,
zIndex: 2,
opacity: (1 / gradientHeight) * (i + 2)
}}
>
</View>
))}
</View>
</View>
);
} else {
return (
<AppLoading
startAsync={getFonts}
onFinish={() => setFontsLoaded(true)}
/>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#0e99b5',
},
centering: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
titleText: {
color: 'orange',
fontSize: 40,
}
});
The error I'm getting is:
Error: Invalid hook call.
I'm just trying to use the custom font and check that the font is loaded before rendering to the screen.
Upvotes: 0
Views: 731
Reputation: 3544
You can't use hooks inside a class component. Hooks are introduced by React to be used in functional components. So you have two options either
I'll suggest that you go with functional component as you are not using any life cycles of class component.
If you go with the first approach you can change your code as below:-
export default class App extends Component {
state = {
fontsLoaded: false,
};
updateFontsLoadedState = () => {
this.setState({ fontsLoaded: true });
}
render() {
const { fontsLoaded } = this.state;
const gradientHeight=500;
const gradientBackground = '#12C1E5';
const data = Array.from({ length: gradientHeight });
if(fontsLoaded){
return (
<View style={styles.container}>
<View style={styles.centering}>
<Text style={styles.titleText}>Test Title</Text>
</View>
<View style={{flex:1}}>
{data.map((_, i) => (
<View
key={i}
style={{
position: 'absolute',
backgroundColor: gradientBackground,
height: 1,
bottom: (gradientHeight - i),
right: 0,
left: 0,
zIndex: 2,
opacity: (1 / gradientHeight) * (i + 2)
}}
>
</View>
))}
</View>
</View>
);
} else {
return (
<AppLoading
startAsync={getFonts}
onFinish={this.updateFontsLoadedState}
/>
);
}
}
}
If you want to use better approach, use hooks and convert this to functional component then you can do that as below:-
export default function App(props) {
const [fontsLoaded ,setFontsLoaded] = useState(false);
const gradientHeight=500;
const gradientBackground = '#12C1E5';
const data = Array.from({ length: gradientHeight });
if(fontsLoaded){
return (
<View style={styles.container}>
<View style={styles.centering}>
<Text style={styles.titleText}>Test Title</Text>
</View>
<View style={{flex:1}}>
{data.map((_, i) => (
<View
key={i}
style={{
position: 'absolute',
backgroundColor: gradientBackground,
height: 1,
bottom: (gradientHeight - i),
right: 0,
left: 0,
zIndex: 2,
opacity: (1 / gradientHeight) * (i + 2)
}}
>
</View>
))}
</View>
</View>
);
} else {
return (
<AppLoading
startAsync={getFonts}
onFinish={() => setFontsLoaded(true)}
/>
);
}
}
Upvotes: 1