react native expo google font usefont.js text error? - react-native

I'm doing a project in react native but i have an issue with my expo google font. I'm pretty new to expo so I have basically no idea on how to fix this bug. The bug only appears on IOS (don't know about android) and works fine on web. The bug appears to be inside useFonts.js which is a file that's part of the expo-google-font.
One of my files using expo-google-font.
import React from "react";
import { Text, TouchableOpacity, Image, StyleSheet } from "react-native";
import { useFonts, Inter_300Light } from "#expo-google-fonts/inter";
import { DefaultWidth } from "./DefaultWidth";
export default function AppleButton() {
let [fontsLoaded] = useFonts({ Inter_300Light });
if (!fontsLoaded) {
return null;
}
return (
<TouchableOpacity style={styles.appleBtnWrapper}>
<Image
style={styles.appleBtnImage}
source={require("../../../assets/third-party-icon/apple.png")}
/>
<Text style={styles.appleBtnText}>Fortsæt med Apple</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
appleBtnText: {
color: "#fff",
fontWeight: "bold",
textAlign: "center",
fontFamily: "Inter_300Light",
fontSize: 16,
},
});
The useFonts.js use useEffect. These are the bugs I'm getting:
Here is the useFonts.js
import { useEffect, useState } from 'react';
import { loadAsync } from 'expo-font';
/**
* Load a map of custom fonts to use in textual elements.
* The map keys are used as font names, and can be used with `fontFamily: <name>;`.
* It returns a boolean describing if all fonts are loaded.
*
* Note, the fonts are not "reloaded" when you dynamically change the font map.
*
* #see https://docs.expo.io/versions/latest/sdk/font/
* #example const [loaded, error] = useFonts(...);
*/
export function useFonts(map) {
let [loaded, setLoaded] = useState(false);
let [error, setError] = useState(null);
useEffect(() => {
loadAsync(map)
.then(() => setLoaded(true))
.catch(setError);
}, []);
return [loaded, error];
}
Here is my App.tsx
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import {registerRootComponent} from 'expo'
import Navigation from './routes'
export default function App() {
return (
<Navigation/>
);
}
registerRootComponent(App);

Firstly install expo-app-loading from here
Then For your fonts create a folder called hooks where your App.js is located and inside that create a file useFonts.js
In useFonts.js write like this -
import * as Font from 'expo-font';
import { Inter_300Light } from '#expo-google-fonts/inter';
export default useFonts = async () => {
await Font.loadAsync({
Inter_300Light: Inter_300Light,
});
};
Your App.tsx should look like this
import { StatusBar } from 'expo-status-bar';
import React, { useState } from 'react';
import { registerRootComponent } from 'expo';
import AppLoading from 'expo-app-loading';
import useFonts from './hooks/useFonts';
import Navigation from './routes';
export default function App() {
const [IsReady, SetIsReady] = useState(false);
const FontLoading = async () => {
await useFonts(); // Font is being loaded here
};
if (!IsReady) {
return (
<AppLoading
startAsync={FontLoading}
onFinish={() => SetIsReady(true)}
onError={() => {}}
/>
);
}
return <Navigation />;
}
registerRootComponent(App);
Now if you want to use these fonts in any files then just simply write the name of the font. You don't need to Import font in every page
For example, your page which uses fonts should look like this
import React from 'react';
import { Text, TouchableOpacity, Image, StyleSheet } from 'react-native';
import { DefaultWidth } from './DefaultWidth';
export default function AppleButton() {
return (
<TouchableOpacity style={styles.appleBtnWrapper}>
<Image
style={styles.appleBtnImage}
source={require('../../../assets/third-party-icon/apple.png')}
/>
<Text style={styles.appleBtnText}>Fortsæt med Apple</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
appleBtnText: {
color: '#fff',
fontWeight: 'bold',
textAlign: 'center',
fontFamily: 'Inter_300Light', // Name of the font..Simple
fontSize: 16,
},
});

Related

Why fontfamily style does not apply to react native project

import React, {useEffect, useState} from 'react';
import {StyleSheet, Text, View} from 'react-native';
import * as Font from 'expo-font';
export default function App() {
const [isFontReady,
setFontReady] = useState(false)
useEffect(() => {
async function loadFont() {
return await Font.loadAsync({sans: require('./assets/fonts/sans.ttf')});
}
loadFont().then(() => {
setFontReady(true)
});
}, []);
return (
<View>
{isFontReady && <Text style={{
fontFamily: 'sans'
}}>
Silence is Golden.
</Text>}
</View>
);
}
Drives me crazy; I can't find the reason why fontFamily style ex: Tahoma has got no effect on a font?
The code looks OK and I even restarted the project by typing >'expo start -c' and reinstalled the packages but no change!

StackNavigation problem in react native app

I am having a problem solving this error. Do I need to render using class components only? or is there a way to use the function method?
Help me if you can.
What would be my best solution?
I have attached code below
EstesGuideNavigator.js
import {createStackNavigator} from 'react-navigation-stack';
import {createAppContainer} from 'react-navigation';
import CategoriesScreen from '../screens/CategoriesScreen';
import PlaceScreen from '../screens/PlacesScreen';
import PlacesDetailScreen from '../screens/PlacesDetailScreen';
const EstesGuideNavigator= createStackNavigator({
Categories: CategoriesScreen, //mapping CategoriesScreen to Categories which makes easier to navigate
Places: {
screen: PlaceScreen
},
PlacesDetail:PlacesDetailScreen
});
export default createAppContainer(EstesGuideNavigator);
Below would be App.js
import React, {useState}from 'react';
import { StyleSheet, Text, View } from 'react-native';
import *as Font from 'expo-font';
import {Apploading} from 'expo';
import EstesGuideNavigator from './navigation/EstesGuideNavigator';
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/>;
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
}
});
CategoriesScreen.js
import React from'react-native';
import {View, Text, StyleSheet} from 'react-native';
const CategoriesScreen = props =>{
return(
<View style ={styles.screen}>
<Text> Categories Screen! Dummy </Text>
</View>
);
};
const styles = StyleSheet.create({
screen:{
flex:1,
justifyContent:'center',
alignItems:'center'
}
});
export default CategoriesScreen;
This is just a dummy screen that i wanted to create.
It was a wrong import that react native automatically changed in my CategoriesScreen.js.

apploading splashscreen with hooks

How do you achieve loading resources while showing the splash screen when you are using functional components with hooks? What is the pattern in using apploading and/or splashscreen with hooks?
Thanks!
Bill
If you only understand Hook's useState, this is a very easy change. This is simply converted into a function, and the state value is resolved using hooks. If you change the example of AppLoading to Hook, the code below is as follows.
AppLoading use Hooks
import React, { useState } from 'react';
import { View ,Image } from "react-native";
import { Asset } from 'expo-asset';
import { AppLoading } from 'expo';
export default function App() {
const [isReady, setReady] = useState(false);
const _cacheResourcesAsync = async () => {
const images = [require('./assets/snack-icon.png')];
const cacheImages = images.map(image => {
return Asset.fromModule(image).downloadAsync();
});
return Promise.all(cacheImages);
}
return (
isReady === false ? ( <AppLoading
startAsync={_cacheResourcesAsync}
onFinish={() => setReady(true)}
onError={console.warn}
/>) : (<View style={{ flex: 1 }}>
<Image source={require('./assets/snack-icon.png')} />
</View>)
);
}

React native snapshot screen

I am building an app for iOS with React native and I would like to know how to take a snapshot of a given screen. I have found this library but I don't know how to use it. Does anyone know how to ?
EDIT:
I used the following code to capture a screen using the library but I get the given error.
try {
captureRef(viewRef, {
format: "jpg",
quality: 0.8
})
.then(
uri => console.log("Image saved to", uri),
error => console.error("Oops, snapshot failed", error)
);
} catch (e) {
console.log(e);
}
The error
ReferenceError: viewRef is not defined
Does anybody know how to fix the error?
Thank you
Sure, but you have to read a little about what a ref is. If you are already using React hooks, check this: https://es.reactjs.org/docs/hooks-reference.html#useref
(if not, just search on how to create a ref in React with createRef)
Basically, a ref is something that will let you identify your component using the same variable even if the component re-renders. So, viewRef in your example should be a reference to a given element. Like:
import React, { useRef } from "react";
function MyComponent() {
const viewRef = useRef();
return <View ref={viewRef}>content</View>
}
So, your draft could be something like:
import React, { useRef } from "react";
import {Button, View, Text} from 'react-native';
import { captureRef } from "react-native-view-shot";
function useCapture() {
const captureViewRef = useRef();
function onCapture() {
captureRef(captureViewRef, {
format: "jpg",
quality: 0.9
}).then(
uri => alert(uri),
error => alert("Oops, snapshot failed", error));
}
return {
captureViewRef,
onCapture
};
}
function MyComponent() {
const { captureViewRef, onCapture } = useCapture();
return (
<>
<View ref={captureViewRef}><Text>content</Text></View>
<Button title="Save" onPress={onCapture} />
</>
);
}
As far as I know, this only generates a temporary file. If you want to see the capture saved into your device, you should use CameraRoll https://facebook.github.io/react-native/docs/cameraroll
I won't cover how to use it here, but it would be something like:
CameraRoll.saveToCameraRoll(uri); // uri being the path that you get from captureRef method
Just notice that your app must ask for proper permission before attempting to save to the device gallery.
hi this can be with the help of react-native-view-shot
this is my parent component
import React, {Component,useRef} from 'react';
import {Platform, StyleSheet, Text, View,Image,Button} from 'react-native';
import { captureRef, captureScreen ,ViewShot} from "react-native-view-shot";
import NewVd from './NewVd';
import Newved from './Newved';
export default class App extends Component {
constructor(){
super();
this.state={
item:null,
captureProcessisReady:false,
myView:false
};
this.func=this.func.bind(this);
}
componentDidMount(){
}
result1=()=>{
console.log("i am here ");
this.setState({captureProcessisReady:true});
}
func = (uri) => {
console.log('ADD item quantity with id: ', uri);
this.setState({item:uri,myView:true});
};
render() {
return (
<View style={styles.container}>
{/* <NewVd
func={this.func}/> */}
<Newved />
<Text>...Something to rasterize...</Text>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<Text style={styles.instructions}>To get started, edit App.js</Text>
<Button onPress={()=>this.result1()} title="press Me"/>
<View>
{this.state.captureProcessisReady?( <NewVd func={this.func}/>):null}
</View>
<View>
{this.state.myView?( <Image source={{uri:this.state.item !== null?`${this.state.item}`:'https://picsum.photos/200'}} style={{width:100,height:100}} />):null}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
this is my child component
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View} from 'react-native';
import ViewShot from "react-native-view-shot";
class NewVd extends Component {
constructor(props){
super(props);
}
onCapture = uri => {
console.log("do something with ", uri);
this.props.func(uri); //for the parent using callback
}
render() {
return (
<ViewShot onCapture={this.onCapture} captureMode="mount">
<Text>...Something to rasterize...</Text>
</ViewShot>
);
}
}
export default NewVd;

passing a prop from index into header component

I'm following a udemy tutorial on react-native.
I'm trying to pass a prop from my index.js into my header.js. The header should say, "Albums". But is is always showing up blank.
If I remove {props.headerText} from header.js and replace it with
"Albums"
then it works. But I'm trying to make the component reusable per the tutorial instructions.
note: I'm using Create React Native App and this is on an android emulator.
App.js
import React from 'react';
import { View } from 'react-native';
import Header from './src/components/header';
export default class App extends React.Component {
render() {
return (
<Header />
);
}
}
index.js
import React from 'react';
import { Text, AppRegistry } from 'react-native';
import Header from './src/components/header';
const App = () => (
<Header headerText={'Albums'} />
);
AppRegistry.registerComponent('albums', () => App);
header.js
import React from 'react';
import { Text, View } from 'react-native';
const Header = (props) => {
const { textStyle, viewStyle } = styles;
return (
<View style={viewStyle}>
<Text style={textStyle}>{props.headerText}</Text>
</View>
);
};
const styles = {
viewStyle: {
justifyContent: 'center'
},
headerStyle: {
fontSize: 20
}
};
export default Header;
Am I missing anything? I've been over and over each file line by line and I can't find any issues.
Thanks!
I would suggest you
const Header = ({props}) => {
const { textStyle, viewStyle } = styles;
return (
<View style={viewStyle}>
<Text style={textStyle}>{props.headerText}</Text>
</View>
);
};
And to pass props ;
const App = () => (
<Header props={someProps} />
);