JSX expressions must have one parent element.ts(2657) react native - javascript

I am new to react native and have tried everything and keep getting the following error
JSX expressions must have one parent element.ts(2657)
I am trying to display information from json in a flatlist.
Here is my code.
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View>
<View style={{backgroundColor: '#808080'}}>
<Text style={styles.MainText}>Sermons</Text>
</View>
<FlatList style={{paddingTop: 30}}
data={ DATA }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={this._renderItem} />
</View>
);
}
_renderItem = ({item}) => {
return(
<View style={{flex:1, flexDirection: 'row', paddingLeft: 10}}>
<Image source={require('./church.png')} style={{width: '100%', height: '25%'}} />
</View>
<View style={{flex: 1, paddingLeft: 20}}>
<Text>{item.title}</Text>
</View>
);
}
}
line 33 ); seems to be causing the problem but I don't know why.

You can't render adjacent elements. They must have some parent element or React.Fragment:
return(
<>
<View style={{flex:1, flexDirection: 'row', paddingLeft: 10}}>
<Image source={require('./church.png')} style={{width: '100%', height: '25%'}} />
</View>
<View style={{flex: 1, paddingLeft: 20}}>
<Text>{item.title}</Text>
</View>
</>
);
<></> is short for <React.Fragment></React.Fragment>

You have 2 view components in return. You should have 1 parent component so you can wrap them into a react fragment.
return(
<>
<View style={{flex:1, flexDirection: 'row', paddingLeft: 10}}>
<Image source={require('./church.png')} style={{width: '100%', height: '25%'}} />
</View>
<View style={{flex: 1, paddingLeft: 20}}>
<Text>{item.title}</Text>
</View>
</>
);

You need to add a container View:
_renderItem = ({item}) => {
return(
<View>
<View style={{flex:1, flexDirection: 'row', paddingLeft: 10}}>
<Image source={require('./church.png')} style={{width: '100%', height: '25%'}} />
</View>
<View style={{flex: 1, paddingLeft: 20}}>
<Text>{item.title}</Text>
</View>
</View>
);
}

Related

react native firebase async await parellel with promise.all

import fire from '../config/fire';
const db = fire.firestore();
class InitialDb extends Component {
constructor(props) {
super(props);
this.state = {
schools: '',
students: '',
};
}
async componentDidMount() {
const { size: schools } = await db.collection('schools').get();
const { size: students } = await db.collection('students').get();
this.setState({ schools, students});
}
render() {
return (
<SafeAreaView>
{/* <StatusBar translucent backgroundColor='#1b75ce' />
<HC title='Dashboard' /> */}
<BackButton />
<View style={{ paddingTop: 10, marginBottom: 20 }}>
<View style={{ flexDirection: 'row' }}>
<View style={styles.widthstyle}>
<TouchableOpacity>
<Card>
<CardItem>
<Body>
<View style={{ flexDirection: 'row' }}>
<Image
style={{ width: 30, height: 30 }}
source={require('../assets/schools.png')}
/>
<Text style={{ textAlign: 'center' }}>
Schools:{this.state.schools}
</Text>
</View>
</Body>
</CardItem>
</Card>
</TouchableOpacity>
</View>
<View style={styles.widthstyle}>
<TouchableOpacity>
<Card>
<CardItem>
<Body>
<View style={{ flexDirection: 'row' }}>
<Image
style={{ width: 30, height: 30 }}
source={require('../assets/asd.png')}
/>
<Text style={{ textAlign: 'center' }}>
Students:{this.state.students}
</Text>
</View>
</Body>
</CardItem>
</Card>
</TouchableOpacity>
</View>
</View>
<View
style={{ flexDirection: 'row' }}
// style={styles.basic1Style}
>
<View style={styles.widthstyle}>
<TouchableOpacity>
<Card>
<CardItem>
<Body>
<View style={{ flexDirection: 'row' }}>
<Image
style={{ width: 30, height: 30 }}
source={require('../assets/def.png')}
/>
<Text style={{ textAlign: 'center' }}>
Office:50
</Text>
</View>
</Body>
</CardItem>
</Card>
</TouchableOpacity>
</View>
<View style={styles.widthstyle}>
<TouchableOpacity>
<Card>
<CardItem>
<Body>
<View style={{ flexDirection: 'row' }}>
<Image
style={{ width: 30, height: 30 }}
source={require('../assets/abc.png')}
/>
<Text style={{ textAlign: 'center' }}>Attended:50</Text>
</View>
</Body>
</CardItem>
</Card>
</TouchableOpacity>
</View>
</View>
</View>
{/* <Text style={{ textAlign: "center" }}>
Swipe from left to right for menu
</Text> */}
<View style={{ marginBottom: 2 }}>
<Text style={{ textAlign: 'center', fontSize: 20, marginBottom: 5 }}>
Search
</Text>
</View>
<Form style={{ marginLeft: 20 }}>
<View style={{ flexDirection: 'row' }}>
<Item style={{ paddingLeft: 20, width: '40%' }}>
<Label style={{ textAlign: 'left' }}>Division</Label>
<Input />
</Item>
<Item style={{ paddingLeft: 20, width: '40%' }}>
<Label style={{ textAlign: 'left' }}>Area</Label>
<Input />
</Item>
</View>
<View style={{ flexDirection: 'row', paddingTop: 20 }}>
<Item style={{ paddingLeft: 20, width: '40%' }}>
<Label style={{ textAlign: 'left' }}>Gang</Label>
<Input />
</Item>
<Item
style={{
borderBottomColor: 'white',
}}
>
<Button info style={{ marginLeft: 25 }}>
<Text> Search </Text>
</Button>
</Item>
</View>
</Form>
{/*<View style={{ flex: 1, marginTop: 3, left: 0, right: 0, bottom: 0 }}>
<MapView
initialRegion={{
latitude: 12.93092,
longitude: 77.602156,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
style={styles.mapStyle}
></MapView>
</View>
*/}
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
basic1Style: {
// flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
},
widthstyle: {
width: Dimensions.get('window').width / 2,
},
mapStyle: {
position: 'absolute',
top: 3,
left: 0,
right: 0,
bottom: 0,
},
});
export default InitialDb;
**This code above is working synchronously and also in series manner. I want this to be in async and await because this is freezing the UI. And also it should update the all 2 state objects after getting the size of all those 2 firestore collections using promise.all.
Here I have updated the code Please check it again **
PROBLEM
The problem here is basically your firebase is initializing on every hot-module reload. You only need to initialize once per App.
So basically, you could wrap your firebase initialization with try-catch and swallow the error.
try {
firebase.initializeApp({
/** config here **/
});
} catch(err) {
console.log(err);
}

Passing param properly to a function in React Native

I'm struggling to pass const navigation = useNavigation(); properly to my outer function.
Currently, I have this 'main' function:
export default function MyDrawer({ route }) {
const nav = useNavigation(); // Use hook here as u will now dont get any error. now pass it as param to above if needed
return (
<NavigationContainer independent={true}>
<Drawer.Navigator
initialRouteName="QR"
drawerContent={props => CustomDrawerContent(props, route)}
>
<Drawer.Screen
name="QR"
component={QR}
initialParams={{ user: route.params.user }}
/>
<Drawer.Screen name="Odabir" component={Odabir} />
</Drawer.Navigator>
</NavigationContainer>
);
}
which handles the drawer logic and routing. I used to declare const Drawer = createDrawerNavigator() in this function:
function CustomDrawerContent({ props, navigation }, route, ) {
// *** Don't use below hook here its wrong to use hooks outside main function if need pass to it as param from main function
// const navigation = useNavigation();
return (
<SafeAreaView style={{ flex: 1 }}>
<View
style={{
height: 150,
alignItems: "center",
justifyContent: "center",
marginTop: Platform.OS === "ios" ? 0 : StatusBar.currentHeight
}}
>
<Image
source={{uri:route.params.user.photoUrl}}
style={{ height: 110, width: 110, borderRadius: 60 }}
/>
</View>
<View style={{ height: 30, alignItems: "center" }}>
<Text style={styles.naslov}>
{route.params.user.name} {route.params.user.lastname}
</Text>
</View>
<View style={{ height: 30, alignItems: "center" }}>
<Text style={styles.naslov}>
{route.params.user.email}
</Text>
</View>
<View style={{ height: 30, alignItems: "center", marginBottom: 10 }}>
<Text style={styles.naslov}></Text>
</View>
<Divider />
<ScrollView style={{ marginLeft: 5 }}>
<TouchableOpacity
style={{ marginTop: 20, marginLeft: 20 }}
onPress={() => props.navigation.navigate("QR")}
>
<View style={{ padding: 10 }}>
<Ionicons name="ios-qr-scanner" size={20} styles={{}}>
<Text style={styles.naslov}> QR</Text>
</Ionicons>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{ marginTop: 20, marginLeft: 20 }}
onPress={() => props.navigation.navigate("Odabir")}
>
<View style={{ padding: 10 }}>
<Ionicons name="ios-qr-scanner" size={20} styles={{}}>
<Text style={styles.naslov}> Odabir</Text>
</Ionicons>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{ marginTop: 20, marginLeft: 20 }}
onPress={() => props.navigation.navigate("Odabir")}
>
<View style={{ padding: 10 }}>
<Ionicons name="ios-qr-scanner" size={20} styles={{}}>
<Text style={styles.naslov}> Odabir</Text>
</Ionicons>
</View>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
);
}
Which handles the onPress routing to different components. I've had to move the const nav = useNavigation(); because of how hooks work and the process of catching data from the Google API.
My question is how do I properly pass the param back to the MyDrawer function so the navigation works again? The error I currently get is TypeError: undefined is not an object(evaluating 'props.navigation')
update code:
export default function MyDrawer({ route }) {
const nav = useNavigation(); // Use hook here as u will now dont get any error. now pass it as param to above if needed
return (
<NavigationContainer independent={true}>
<Drawer.Navigator
initialRouteName="QR"
drawerContent={props => <CustomDrawerContent {...props} {...{route}} />}
>
<Drawer.Screen
name="QR"
component={QR}
initialParams={{ user: route.params.user }}
/>
<Drawer.Screen name="Odabir" component={Odabir} />
</Drawer.Navigator>
</NavigationContainer>
);
}
Drawer Content
const CustomDrawerContent = ({navigation, route}) => {
// *** Don't use below hook here its wrong to use hooks outside main function if need pass to it as param from main function
// const navigation = useNavigation();
return (
<SafeAreaView style={{ flex: 1 }}>
<View
style={{
height: 150,
alignItems: "center",
justifyContent: "center",
marginTop: Platform.OS === "ios" ? 0 : StatusBar.currentHeight
}}
>
<Image
source={{uri:route.params.user.photoUrl}}
style={{ height: 110, width: 110, borderRadius: 60 }}
/>
</View>
<View style={{ height: 30, alignItems: "center" }}>
<Text style={styles.naslov}>
{route.params.user.name} {route.params.user.lastname}
</Text>
</View>
<View style={{ height: 30, alignItems: "center" }}>
<Text style={styles.naslov}>
{route.params.user.email}
</Text>
</View>
<View style={{ height: 30, alignItems: "center", marginBottom: 10 }}>
<Text style={styles.naslov}></Text>
</View>
<Divider />
<ScrollView style={{ marginLeft: 5 }}>
<TouchableOpacity
style={{ marginTop: 20, marginLeft: 20 }}
onPress={() => props.navigation.navigate("QR")}
>
<View style={{ padding: 10 }}>
<Ionicons name="ios-qr-scanner" size={20} styles={{}}>
<Text style={styles.naslov}> QR</Text>
</Ionicons>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{ marginTop: 20, marginLeft: 20 }}
onPress={() => props.navigation.navigate("Odabir")}
>
<View style={{ padding: 10 }}>
<Ionicons name="ios-qr-scanner" size={20} styles={{}}>
<Text style={styles.naslov}> Odabir</Text>
</Ionicons>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{ marginTop: 20, marginLeft: 20 }}
onPress={() => props.navigation.navigate("Odabir")}
>
<View style={{ padding: 10 }}>
<Ionicons name="ios-qr-scanner" size={20} styles={{}}>
<Text style={styles.naslov}> Odabir</Text>
</Ionicons>
</View>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
);
}

Style in react-native

I'm trying to adjust the homepage but I don't know how to change the position of the Text.
I have this code:
return (
<View style={style.container}>
<View style={style.page}>
<Icon
name="user-circle"
color="#56cbbe"
size={70}
onPress={() => Actions.visualizzaprofilo({ cf: Username })}
/>
<Text
style={{
paddingBottom: 15,
textAlign: "center",
fontSize: 15,
color: "#56cbbe",
fontWeight: "bold"
}}
onPress={() => Actions.visualizzaprofilo({})}
>
Visualizza il Profilo
</Text>
<Text style={{ textAlign: "center", fontSize: 20 }}>
{"Benvenuto"}
</Text>
<Text
style={{
textAlign: "center",
fontSize: 20,
color: "#56cbbe",
fontWeight: "bold"
}}
>
<TouchableOpacity
style={[style.button, style.buttonOK]}
onPress={() => this.checkFunction()}
>
<Text style={style.buttonTesto}>Inizia</Text>
</TouchableOpacity>
{this.modProfilo({ })}
{this.eliminaProfilo({ })}
{this.sensorCheck()}
{this.logout()}
</View>
</View>
Where for example modProfilo (and also the other have the same style):
modProfilo({}) {
<Text
style={{ color: "#56cbbe", paddingTop: 20 }}
onPress={() => Actions.modificaprofilo({ })}
>
MODIFICA PROFILO
</Text>
I need to transform the first image in the second one, how can i Do??
Enclose them in a view with flexDirection set to row and justifyContent set to space-between:
return (
<View style={style.container}>
...
<View style={{flexDirection:'row', justifyContent:'space-between'}}>
{this.modProfilo({ })}
{this.eliminaProfilo({ })}
{this.sensorCheck()}
{this.logout()}
</View>
...
</View>
flexDirection: 'row'
This will do the required job. BY default the flex direction is vertical. U just need to change into horizontal.
Added a View (let id be OuterView) and add button inside it. Add below styles in your code:
OuterView: {
flex: 1,
flexDirection: 'row',
},
buttonsStyle: {
flex: 1,
}

How to make button disabled if all checkbox are unchecked in react native

There are 3 check boxes and I have to make one check box mandatory . Like if all checkbox are un checked then button should be disabled . Please help me for that . How I can do .
<View style={{ flexDirection: 'row', paddingLeft: 15 }}>
<View style={{ flex: 1 }}>
<CheckBox color="#00678f"
checked={this.state.notification.isContactByPost}
onPress={() => this.handleChange('isContactByPost')}
/>
</View>
<View style={{ flex: 1 }}>
<Text style={{ fontSize: 14 }}>Post</Text>
</View>
<View style={{ flex: 1 }}>
<CheckBox color="#00678f"
checked={this.state.notification.isContactByEmail}
onPress={() => this.handleChange('isContactByEmail')}
/>
</View>
<View style={{ flex: 1 }}>
<Text style={{ fontSize: 14 }}>Email</Text>
</View>
<View style={{ flex: 1 }}>
<CheckBox color="#00678f"
checked={this.state.notification.isContactBySms}
onPress={() => this.handleChange('isContactBySms')}
/>
</View>
<View style={{ flex: 1 }}>
<Text style={{ fontSize: 14 }}>SMS</Text>
</View>
</View>
<View style={{ marginTop: 50 }}>
<PrimaryBtn
label={'submit'}
disabled={false}
onPress={() => this.OnButtonClick(this.state.notification)}
/>
</View>
</View>
Thanks
This is how you can do it
<PrimaryBtn label={'submit'} disabled={!this.state.notification.isContactByPost &&
!this.state.notification.isContactByEmail &&
!this.state.notification.isContactBySms} onPress={() =>
this.OnButtonClick(this.state.notification)} />
Hope this helps
Try this (to make it more simple i removed redundant parts) =>
const {isContactByPost, isContactByEmail, isContactBySms} = this.state.notification
const isButtonDisabled = !(isContactByPost || isContactByEmail || isContactBySms)
<PrimaryBtn disabled={isButtonDisabled} /> // don't forget your others props :)
render(){
const {isContactByPost,isContactByEmail,isContactBySms } = this.state.notification;
return (
<PrimaryBtn
label={'submit'}
disabled={!(isContactByPost || isContactByEmail || isContactBySms)}
onPress={() => this.OnButtonClick(this.state.notification)}
/>
);
}

How to place two buttons within the same row in react native?

Within a popup dialog I want to buttons to be placed on the same line but now I'm getting like this https://i.stack.imgur.com/sJ30p.png.Following is the style given.
<PopupDialog
ref={popupDialog => {
this.popupDialog = popupDialog;
}}
dialogStyle={{ backgroundColor: "#ddd", height: 200, width:320, border:10,padding:10}}
overlayBackgroundColor="#fff"
dismissOnTouchOutside={true}
>
<View style={styles.dialogContentView}>
<Text style={{fontSize:18}}>Are you sure you want to submit?</Text>
<View style={styles.button_1}>
<Button
title="Yes"
onPress={() => {
console.log('clicked')
}}
/>
</View>
<View style={styles.button_1}>
<Button
title="No"
onPress={() => {
console.log('clicked')
}}
/>
</View>
</View>
</PopupDialog>
.....
....
dialogContentView: {
flex: 1,
flexDirection: 'column',
justifyContent: 'space-between'
},
button_1:{
width: '40%',
height: 30,
}
Add View parent to both Button component with style flexDirection: 'row' after </Text>
<View style={{ flexDirection: 'row' }}>
<View style={styles.button_1}>
<Button
title="Yes"
onPress={() => {
console.log('clicked');
}}
/>
</View>
<View style={styles.button_1}>
<Button
title="No"
onPress={() => {
console.log('clicked');
}}
/>
</View>
</View>
You can try this snack
Try this for full width without any spaces or margin JUST COPY PASTE
<View style={{ flexDirection: "row" }}>
<View style={{ flex: 1 }}>
<TouchableOpacity style={{ alignSelf: 'stretch',backgroundColor: '#2980B9' }} onPress={() => { onSavePress }}>
<Text style={{ alignSelf: 'center',
color: '#ffffff',
fontSize: 16,
fontWeight: '600',
paddingTop: 10,
paddingBottom: 10 }}>Save</Text>
</TouchableOpacity>
</View>
<View style={{borderLeftWidth: 1,borderLeftColor: 'white'}}/>
<View style={{ flex: 1}}>
<TouchableOpacity style={{ alignSelf: 'stretch',backgroundColor: '#2980B9'}} onPress={() => { onCancelPress }}>
<Text style={{ alignSelf: 'center',
color: '#ffffff',
fontSize: 16,
fontWeight: '600',
paddingTop: 10,
paddingBottom: 10 }}>Cancel</Text>
</TouchableOpacity>
</View>
</View>
To do that, I usually create a view, set its flexDirection to 'row' and put the button components inside of it. So, your code would look like this:
<View style={{ flexDirection: 'row' }}>
<Button title='Button 1'/>
<Button title='Button 2'/>
</View>
I hope it helps.

Categories

Resources