React Native Project Structure Issue - reactjs

I’ve just started using react native and expo and I’ve been restructuring folders over and over again because I run into multiple errors where a js file can’t find an image that’s located under ./asses/navigation/the_image.png. The only time I got it to work was having all the js files within the App.js and have the App.js located under “./” and the pictures in the same location.
This is what the error looks like: error
And this is what my project structure looks like: project structure
What’s the proper way to structure my project and how can I get files such as my profile.js to find images in assets?
Code for messages.js:
import 'react-native-gesture-handler';
import React, { useState } from 'react';
import { Image, StyleSheet, TouchableOpacity, View, TextInput } from 'react-native';
export default function messages({ navigation })
{
const [filtertext, setfilter] = useState('');
return(
<View style={styles.home_container}>
<View style={styles.home_background}>
<TextInput
style= {styles.filter}
placeholder= "Search"
placeholderTextColor= "#96a7af"
onChangeText={filtertext => setfilter(filtertext)}
defaultValue={filtertext}
/>
<Image source= {require ('./assets/navigation/3_Elements_Circled_Navigation_Message_On.png')}/>
<TouchableOpacity onPress={() =>navigation.navigate('Home')} style={styles.home_button}>
<Image source= {require ('./assets/buttons/new_message_icon.png')} style={styles.new_msg_buton}/>
</TouchableOpacity>
<TouchableOpacity onPress={() =>navigation.navigate('Profile')} style={styles.profile_button}>
<Image source= {require ('./assets/buttons/profile_icon.png')}/>
</TouchableOpacity>
</View>
</View>
);
}
const styles = StyleSheet.create(
{
new_msg_buton:
{
position:'absolute',
height: 60,
width: 60,
top: -696,
left: 129,
},
filter:
{
position: 'absolute',
height: 54,
width: 275,
top: -660,
left: 19,
paddingLeft: 20,
borderColor: 'black',
borderRadius: 23,
borderTopWidth: 3,
borderBottomWidth: 3,
borderLeftWidth: 3,
borderRightWidth: 3,
}
})

Using ./ refers to the current directory the file is located in
Using ../dir_onelevel_above refers to the dir_onelevel_above as you've gone one level above in the folder structure.
That being said, your should need ../assets/navigation/icon.png to access the image from messages.js

Related

In NativeBase, how can I avoid inline styling props of component and write it separately and then pass it

I am just trying to write a clean code and avoid lots thing in same tag. For example: Text and Box component have could have so many styling props, So is there any way I can write it separately and they pass it as a whole object as style.
import { Box, extendTheme, NativeBaseProvider, Progress, Text, View } from 'native-base'
import React, { FC } from 'react'
const TrainingList: FC = () => {
return (
<NativeBaseProvider>
<Box my="2">
<Text fontSize="16" lineHeight="21.8" bold> Annual Training </Text>
<View my="2" >
<Text fontSize="14" lineHeight="19.8"> Due in 2 days (01/12/22) </Text>
<Text fontSize="14" lineHeight="19.8"> 50% complete / 10 hrs left </Text>
</View>
<Progress rounded="12" colorScheme="warning" bg="#D7D7D7" size="sm" value={65} mx={0} />
</Box>
<Box mt="5">
This is Box2
</Box>
</NativeBaseProvider>
)
}
export default TrainingList
In my eyes, the best approach will be to add variants to the NativeBase Text and Box component. It'll keep your code but also you'll be able to share consistent style throughout the codebase.
And if you wanna know HOW? I'm sharing a few resources to follow.
Resource:
Official Docs: First place to go.
Snack: A demo snack to show how to add variants.
Blog: To better understand how to effectively customise NativeBase components.
You can use StyleSheet for that. You can use what you defined under styles on components.
import React from "react";
import { StyleSheet, Text, View } from "react-native";
const App = () => (
<View style={styles.container}>
<Text style={styles.title}>React Native</Text>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 24,
backgroundColor: "#eaeaea"
},
title: {
marginTop: 16,
paddingVertical: 8,
borderWidth: 4,
borderColor: "#20232a",
borderRadius: 6,
backgroundColor: "#61dafb",
color: "#20232a",
textAlign: "center",
fontSize: 30,
fontWeight: "bold"
}
});
export default App;
Yes, that's possible using styled components. You can accept props inside of your styling. Alternatively, I prefer using stylesheets as it's simpler and still keeps your code clean. Ex:
<Box style={styles.boxMain}>
<Text style={styles.textOneStyle}> Annual Training </Text>
<View my="2">
<Text style={styles.textTwoStyle}> Due in 2 days (01/12/22) </Text>
<Text style={styles.textTwoStyle}> 50% complete / 10 hrs left </Text>
</View>
</Box>
);
};
const styles = StyleSheet.create({
textOneStyle: {
fontSize: 16,
lineHeight: 21.8,
fontWeight: "bold"
},
textTwoStyle: {
fontSize: 14,
lineHeight: 19.8,
},
});

React Native: Is there any way to make inline styles having a state to turn out external styles?

How can I combine an external style with an inline style which has a state? I just want to place all styles into the style module.
<View
style={[
styles.buttonAcceptDinamic,
{
backgroundColor: !this.state.micState ? null : 'rgba(255,255,255,.4)',
},
]}>
<Icon
name={this.state.micState ? 'mic-off' : 'mic'}
color="white"
size={30}
/>
</View>;
(React native: How to combine external and inline styles?) This solution has an inline style having no state.
Edited: Code works properly. I just wanted to get rid of inline styling having state because VSCode and Error Lens(VSCode Extension) gives me a warning.
If I understand the question correctly:
<View
style={{
...styles.buttonAcceptDinamic,
backgroundColor: !this.state.micState ? null : 'rgba(255,255,255,.4)',
}}>
</View>
Using the spread operator seems the best way to go.
An example using hooks but achieves the same thing, you had an issue with your syntax:
<Text style={[styles.paragraph, isValid ? {'color': 'red'} : "" ]}>
Expo: https://snack.expo.io/rLwktDEHM
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default function App() {
const [isValid, setValid] = React.useState(false);
return (
<View style={styles.container}>
<Text style={[styles.paragraph, isValid ? {'color': 'red'} : "" ]}>
Change code in the editor and watch it change on your phone! Save to get a shareable url.
</Text>
<TouchableOpacity onPress={() => setValid(v => !v)}>
<Text>
Change State
</Text>
</TouchableOpacity>
<Card>
<AssetExample />
</Card>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});

fontFamily unrecognized in react native ios app

I'm struggling to get my font, PressStart2P, loaded on. Its a font from google fonts. . . Have gone through the following steps, multiple times, to make sure I wasnt sloppy. By all indications, the font should be available in the react native app.
created the assets folder at the root of my project directory
create the fonts folder within the assets folder and place the font files inside... exactly as the PostScript name indicates, and have used both .otf and .ttf versions of the font.
in package.json, specified where the custom fonts are located:
"rnpm": {
"assets": [
"./assets/fonts/"
]
},
in my terminal, entered npx react-native link
added my fonts in App.js
For reference, here is the entire App.js file:
import React, { Component } from 'react';
import { Text, View , TouchableOpacity} from 'react-native';
export default class HelloWorldApp extends Component {
render() {
return (
<View style={{ backgroundColor:'#e9ffc945',flex: 1,
justifyContent: "center", alignItems: "center" }}>
<Text style={{fontSize:26, color: "#85321b45",
fontFamily: "PressStart2P"}}>Allah'u'Abha :)</Text>
<TouchableOpacity
style={{
backgroundColor:'#a4a6fc19',
padding: 95,
borderRadius: 19,
}}
>
<Text
style={{
color: "white",
fontSize: 20
}}
>
</Text>
</TouchableOpacity>
</View>
);
}
}
Additionally, I've checked in my copy bundle resources, in my project target in xcode... the file is there. Any ideas out there ?
I think you are using Font Family name which is not recognized with iOS. Instead of Font Family name, you should use PostScript Name of each font
Open Font Book ( Spotlight type FontBook )
Select your Font and view more information and it will look like this
You need to give PostScript name of the font as fontFamily . Otherwise android will work but iOS will give errors.
This is updated codebase of your App.js
import React, { Component } from 'react';
import { Text, View , TouchableOpacity} from 'react-native';
export default class HelloWorldApp extends Component {
render() {
return (
<View style={{ backgroundColor:'#e9ffc945',flex: 1,
justifyContent: "center", alignItems: "center" }}>
<Text style={{fontSize:26, color: "#85321b45",
fontFamily: "PressStart2P-Regular"}}>Allah'u'Abha :)</Text>
<TouchableOpacity
style={{
backgroundColor:'#a4a6fc19',
padding: 95,
borderRadius: 19,
}}
>
<Text
style={{
color: "white",
fontSize: 20
}}
>
</Text>
</TouchableOpacity>
</View>
);
}
}
After that link your assets again and clean project using xcode and rebuild.
Now you are ready to go...
Make sure you have link your assets and clean project before running
The recommended way is to create your own component, such as MyAppText. MyAppText would be a simple component that renders a Text component using your universal style and can pass through other props, etc.
https://facebook.github.io/react-native/docs/text.html#limited-style-inheritance

How to design fieldset legend using react-native

In HTML we can use fieldset-legend like this:
Code:
<fieldset>
<legend>Heading</legend>
</fieldset>
O/P:
How can I design the same things using react-native? Here I got a technique where it created text with a straight line, but I want to design it like fieldset-legend. How can I do that?
I got a technique to create this fieldset-legend without any library/package. Here is my JSX code:
JSX view:
<View style={styles.fieldSet}>
<Text style={styles.legend}>Heading</Text>
<Text>Some Text or control</Text>
</View>
JSX style:
const styles = StyleSheet.create({
fieldSet:{
margin: 10,
paddingHorizontal: 10,
paddingBottom: 10,
borderRadius: 5,
borderWidth: 1,
alignItems: 'center',
borderColor: '#000'
},
legend:{
position: 'absolute',
top: -10,
left: 10,
fontWeight: 'bold',
backgroundColor: '#FFFFFF'
}
});
You could you Readymade package - react-native-fieldset
Its very easy to work with it.
You could directly do-
import FieldSet from 'react-native-fieldset';
import { View, Text } from 'react-native';
//...
return (
<View>
<FieldSet label="Fieldset label">
<Text>Field Set Body</Text>
</FieldSet>
</View>
);
//...
This FieldSet is not working
import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity, SafeAreaView, TextInput } from 'react-native';
import FieldSet from 'react-native-fieldset';
import LinearGradient from 'react-native-linear-gradient'
// create a component
export default function MyComponent() {
return (
<View>
<FieldSet label="Fieldset label" label2='try'>
<TextInput placeholder='House Name/ Number'/>
</FieldSet>
</View>
);
};

React Native ScrollView with single child component

I want to have a fullscreen ScrollView which contains all of the contents of my Home screen in my app. The issue I'm facing is that it works as expected when I have two child components for the ScrollView (I added a Text component just to try it), but not if I just have the single content View that I want.
The contents of <View style={style.content}> are taller than the screen size, so it should scroll. But when I remove <Text style={{margin: 60, marginTop: 800}}>Here is some text</Text> the entire screen goes white.
Here's what I've heard about ScrollView:
It needs a limited height (but I should have that since all of the content is currently static (no dynamic data) and all of my components there have a fixed height)
You need to use {flex: 1} on the components inside the ScrollView (I have this style set on my Container component)
Here is my Home component:
import React, { Component } from "react";
import {
StatusBar, StyleSheet, View, ScrollView, Text
} from "react-native";
import { LinearGradient } from "expo";
import MaterialCommunityIcon from "react-native-vector-icons/MaterialCommunityIcons"
import Color from "color";
import globalStyles from "../config/globalStyles";
import Container from "../components/Container/Container";
import Header from "../components/Header/Header";
import FullWidthImage from "../components/Images/FullWidthImage";
import MainFeedbackText from "../components/Text/MainFeedbackText";
import MainStatistics from "../components/Statistics/MainStatistics";
import Button from "../components/Buttons/Button"
export default class Home extends Component {
render() {
return (
<ScrollView style={{borderColor:"red", borderWidth: 2}}>
<Container>
<View style={style.content}>
<MainFeedbackText/>
<Button
text="START NEW WORKOUT"
textStyle={{fontSize: 24}}
buttonStyle={{
backgroundColor: globalStyles.colors.green,
paddingHorizontal: 20,
}}
icon={<MaterialCommunityIcon style={style.settings} name="dumbbell" color="white" size={30}/>}
/>
<Button
text="My workouts"
textStyle={{fontSize: 24, paddingRight: 40}}
buttonStyle={{
backgroundColor: Color("black").fade(0.8),
paddingHorizontal: 20,
margin: 20
}}
icon={<MaterialCommunityIcon style={style.settings} name="format-list-bulleted" color="white" size={20}/>}
/>
<MainStatistics/>
</View>
{/**TODO: ScrollView breaks when removing this line*/}
<Text style={{margin: 60, marginTop: 800}}>Here is some text</Text>
<StatusBar translucent={false}/>
<LinearGradient colors={["transparent", globalStyles.colors.dark]} style={style.gradient}>
<View style={style.image}>
<FullWidthImage requireSource={require("./lifting.jpg")}/>
</View>
</LinearGradient>
<Header/>
</Container>
</ScrollView>
);
}
}
const style = StyleSheet.create({
image: {
opacity: 0.3,
zIndex: -1,
},
gradient: {
position: "absolute",
top: 0,
zIndex: -1
},
content: {
flex: 1,
position: "absolute",
top: 80,
height: 4000,
}
});
Set contentContainerStyle={{ flex: 1 }} for ScrollView to become fullscreen.

Resources