Trouble connecting external files to App.js in react native - javascript

I'm super new to react native & having a hard time connecting separate files with my App.js. I've got a user-defined component in a separate file. This is what I've right now in the app.js
import React from 'react';
import TextImg from "./components/comp";
import { StyleSheet, Text, View, Image } from 'react-native';
export default function App() {
return (
<View style={{alignItems:'center', top:150}}>
<Image source={require('./images/pic.jpeg')} style={{ width: 290, height: 190 }}/>
<TextImg text='Mt. Fuji'/>
<TextImg source={{imageUri: 'https://reactjs.org/logo-og.png'}} style={{width: 400, height: 400}} />
</View> );
};
I am importing components from comp.js, and this is what I've in the comp.js file
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
function TextImg(textprop, imgprop) {
return (
<React.Fragment>
<Text>{textprop.text}</Text>
<Image source={imgprop.imageUri}></Image>
</React.Fragment>
);
};
But this only shows the text, but not the image. Can anyone help with this?
Thanks in advance for help!

All your props would be passed as a single parameter. So you should change your component like below.
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
export default function TextImg(props) {
return (
<React.Fragment>
<Text>{props.text}</Text>
<Image source={props.imageUri} style={props.style}></Image>
</React.Fragment>
);
};
You will have to import it in your app.js. (Assuming your file name is TextImg.js and its in the same path)
import TextImg from './TextImg'

You are not passing your props correctly.
Here is a revamp of your code, but in the proper way:
import React from 'react';
import { TextImg } from "./components/comp";
import { StyleSheet, Text, View, Image } from 'react-native';
export default function App() {
return (
<View style={{alignItems:'center', top:150}}>
<Image source={require('./images/pic.jpeg')} style={{ width: 290, height: 190 }}/>
<TextImg text='Mt. Fuji' imageUri: {'https://reactjs.org/logo-og.png'} />
</View> );
};
Then in comp.js
import React from 'react';
import { StyleSheet, Text, View, Image } from 'react-native';
export const TextImg = ({ text, imageUri }) => {
return (
<React.Fragment>
<Text>{text}</Text>
<Image source={imageUri} style={{width: 400, height: 400}} />
</React.Fragment>
);
};
This will fix it up for you. Study the code and try to understand what was done. But I'll also advise you to learn about React props.

Related

React Native, onPress not firing

Cannot get any output from my function test() which I have written in Boxes.js when I add onPress={test} to my View tag in Dice.js.
I have tried to add test() on tags like Text, then it works, but not when I put it on the View tag.
Boxes.js:
import react from "react";
import { StyleSheet, Text, View, Image } from "react-native";
import Dice from "./Dice";
import PatternDivider from "./PatternDivider";
export function test() {
console.log("hi");
}
export default class Boxes extends react.Component {
render() {
return (
<View style={styles.box}>
<Text style={styles.header}>Advice #117</Text>
<Text style={styles.advice}>
It is easy to sit up and take notice, what's difficult is getting uu
and taking action
</Text>
<PatternDivider />
<Dice />
</View>
);
}
}
Dice.js:
import react from "react";
import { StyleSheet, Text, View, Image } from "react-native";
import { test } from "./Boxes";
export default class Dice extends react.Component {
render() {
return (
<View style={styles.circle} onPress={test}>
<Image
source={require("../assets/icon-dice.png")}
style={styles.dice}
/>
</View>
);
}
}
If you wanna Dice to be clickable, use one the components that handles press events, like Pressable. Not all components accept an onPress property, View is one of them.
import react from "react";
import { StyleSheet, Text, View, Image, Pressable } from "react-native";
import { test } from "./Boxes";
export default class Dice extends react.Component {
render() {
return (
<Pressable style={styles.circle} onPress={test}>
<Image
source={require("../assets/icon-dice.png")}
style={styles.dice}
/>
</Pressable>
);
}
}
React Native's View component doesn't have an onPress property https://reactnative.dev/docs/view

React Native Expo error: Hooks can only be called inside the body of a function component

I am developing mobile app using React Native expo.. I am getting the following exception:
Invalid hook call. Hooks can only be called inside the body of a function component....
I have gone through the other answers posted here on SO and have confirmed that the hook in my code is indeed inside a function. But still I am unable to resolve the error. KIndly help. Please see my code below. Let me know if more clarification is needed.
import React, { useState, useEffect } from 'react';
import { SafeAreaView, StatusBar, Button, View, Platform , Text} from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import Constants from 'expo-constants';
const statusBarPadding = Platform.OS === 'android' ? StatusBar.currentHeight: 0;
export default function OpenGallery () {
const [image, setImage] = useState(null);
useEffect(() => { // hook is inside function but still getting error
(async () => {
if (Platform.OS !== 'web') {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') {
alert('Sorry, we need camera roll permissions to make this work!');
}
}
})();
}, []);
return (
<SafeAreaView style={{ paddingTop: statusBarPadding }}>
<Text> Some text </Text>
</SafeAreaView>
);
}
Second file:
import React from 'react';
import { SafeAreaView, StatusBar, Button, View, Platform , Text} from 'react-native';
import OpenGallery from './OpenGallery'
const statusBarPadding = Platform.OS === 'android' ? StatusBar.currentHeight: 0;
export default function CameraScreen() {
return (
<SafeAreaView style={{ paddingTop: statusBarPadding }}>
<Text> Upload image from gallery.</Text>
<Button title="Select from Gallery" onPress={OpenGallery} />
</SafeAreaView>
);
}
it is in fact not being called from inside the component. you are calling it from the JSX, which is entirely different. there are two issues here that break the rules of hooks.
hooks must be called unconditionally. you are breaking that rule here.
<Button title="Select from Gallery" **onPress={OpenGallery}** />
Hooks must be called from inside a functional component. you cannot import another component and call it as a function. this is what you're doing. you are calling the react component on a onPress method which is wrong.
What can you do to fix it?
bring the state down. make the check to see if it's on a web or a mobile in the second file itself. i would post the code but i don't have expo installed at the moment.
It might sound out of scope here but I think in your case, you need to specify the behaviour on how do you want the OpenGallery to appear after pressing the button on CameraScreen... you may be using navigation (may be react-navigation) or using a modal.
Let's say you're using react-navigation. (as you're using expo, it's normally included in the project) https://reactnavigation.org/
On CameraScreen
export default function CameraScreen({navigation}) {
const gotoOpenGallery = () => {
navigation.navigate('OpenGallery');
}
return (
<SafeAreaView style={{ paddingTop: statusBarPadding }}>
<Text> Upload image from gallery.</Text>
<Button title="Select from Gallery" onPress={gotoOpenGallery} />
</SafeAreaView>
);
}
You will also need to create a StackNavigator
Your App.js (or your entry point of the app)
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import OpenGallery from './OpenGallery';
import CameraScreen from './CameraScreen';
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="CameraScreen" component={CameraScreen} />
<Stack.Screen name="OpenGallery" component={OpenGallery} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;

undefined is not an object (evaluating '_react.React.Component')

I am developing an app in react-native while running the app I get this error.
My index.js file
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
My App.js file
import { StyleSheet, View, StatusBar } from 'react-native';
import Routes from './src/store/Routes';
import 'react-native-gesture-handler';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<StatusBar backgroundColor="#18163E" barStyle="light-content" />
<Routes />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexGrow: 1,
},
}); ```
While running i am getting above error and it is pointed to index.js file
This is missing.
import React, { Component } from 'react';
Your error message clearly states the React component missing.
In your App.js file add the below line:
import React, { Component } from 'react';
All of your react components should have this line.
After adding the above line your App.js file will appear as below:
import React, { Component } from 'react';
import { StyleSheet, View, StatusBar } from 'react-native';
import Routes from './src/store/Routes';
import 'react-native-gesture-handler';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<StatusBar backgroundColor="#18163E" barStyle="light-content" />
<Routes />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexGrow: 1,
},
});
Did you forget to import AppRegistry from react-native?

Call a function inside a React hook is possible

I have a component like below based on Hooks
import React, { useEffect, useState } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Animated
} from 'react-native';
import CAStyles from '../res/CAStyles';
const CACard = (props ) => (
<TouchableOpacity onPress={props.cardTouched}>
<View style={[styles.cardContainer, CAStyles.ALIGN_CENTER]} width={props.width} height={props.height}>
<Text style={styles.textStyle}>{props.title}</Text>
</View>
</TouchableOpacity>
);
export default CACard
I'd like to have own state values and functions inside the hook. But it is throwing syntax error. I know it is possible with Class based components but not sure why it is not possible with Hooks.
My subsequent attempts to find a solution is futile. Can someone help me out here. Thanks in advance.
Thanks to #JMadelaine for pointing it out. I changed as below and it all works fine.
const CACard = (props ) => {
return (
<TouchableOpacity onPress={props.cardTouched}>
<View style={[styles.cardContainer, CAStyles.ALIGN_CENTER]} width={props.width} height={props.height}>
<Text style={styles.textStyle}>{props.title}</Text>
</View>
</TouchableOpacity>
)
};
As JMadelaine correctly pointed out. You need to write useState inside functional component definition. Restructure your code like this:
import React, { useEffect, useState } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Animated
} from 'react-native';
import CAStyles from '../res/CAStyles';
const CACard = (props) =>{
const [aStateVar, setAStateVar] = useState(false);
return (
<TouchableOpacity onPress={props.cardTouched}>
<View style={[styles.cardContainer, CAStyles.ALIGN_CENTER]} width={props.width} height={props.height}>
<Text style={styles.textStyle}>{props.title}</Text>
</View>
</TouchableOpacity>
);
};
export default CACard;

reactnavigation hiding statusbar leaves space above header

I use reactnavigation and I am hiding the statusbar at the top, but it leaves an empty space above the header.
I already tried paddingTop or marginTop, but none work.
This is how I hide the statusbar.
import React from 'react';
import { Platform, View, StatusBar } from 'react-native';
import { Tabs, Drawer } from './config/router';
const App = () => (
<View style={{flex:1}}>
<StatusBar hidden={true} />
<Drawer />
</View>
);
export default App;
Any idea would be helpful.
Thanks.
How to Fix it
I add the following to the index.js:
import React from 'react';
import { Platform, View, StatusBar } from 'react-native';
import { Tabs, Drawer } from './config/router';
import { SafeAreaView } from 'react-navigation';
SafeAreaView.setStatusBarHeight(0);
const App = () => (
<View style={{flex:1}}>
<StatusBar hidden={true} />
<Drawer />
</View>
);
export default App;
Basically added the SafeAreaView part.
Hope this is helpful for others.
Try the static function Status Bar. You might need to convert the component to a React Component/Pure Component. Try it with and without converting it.
componentDidMount(){
StatusBar.setHidden(true,true);
}

Categories