Hi I am New React Native. I'm experimenting with dummy data came across with this. I'm using 0.69.5 version and using Expo. Could anyone please look at this code find out what's wrong. and if there is any alternative solution. I have created two Touchable Opacity. On Press It changes the list to the below container
a big Thankyou in advance
import {
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native";
import React, { useState } from "react";
import Header from "../StaticComponents/Header";
const LoansScreen = () => {
const [retail, setRetail] = useState(true);
const retailData = [
{
id: 1,
title: "Personal Loan",
},
{
id: 2,
title: "Home Loan",
},
{
id: 3,
title: "Car Loan",
},
{
id: 4,
title: "Agri & Rural Loan",
},
{
id: 5,
title: "Instant Car Loan Top Up",
},
{
id: 6,
title: "Loan Against Property",
},
{
id: 7,
title: "Loan Against Fixed Deposit",
},
{
id: 8,
title: "Education Loan - Higher Studies",
},
{
id: 9,
title: "Two Wheeler Loans",
},
{
id: 10,
title: "24x7 Loan Against Securities",
},
];
const businessData = [
{
id: 101,
title: "Business Loan",
},
{
id: 102,
title: "Doctor Loan",
},
{
id: 103,
title: "Cash Credit",
},
{
id: 104,
title: "Overdraft",
},
{
id: 105,
title: "Overdraft Renewal",
},
{
id: 106,
title: "Secured Term Loan",
},
{
id: 107,
title: "Merchant Loan",
},
{
id: 108,
title: "Trade Finance",
},
{
id: 109,
title: "Digital Business Loan",
},
];
return (
<View>
<View style={[styles.divider, { marginTop: 2 }]}></View>
<View
style={{
alignItems: "flex-start",
justifyContent: "space-evenly",
flexDirection: "row",
padding: 10,
}}
>
<TouchableOpacity onPress={() => setRetail(true)}>
<Text style={styles.heading}> Retail </Text> <----- First Touchable
</TouchableOpacity>
<TouchableOpacity onPress={() => setRetail(false)}>
<Text style={styles.heading}>Business</Text> <----- Second Touchable
</TouchableOpacity>
</View>
<View style={[styles.divider, { marginBottom: 10 }]}></View>
{!!retail ? ( //Error Lies in this area
<ScrollView showsVerticalScrollIndicator={false}>
{retailData.map((item, index) => (
<View key={index}>
<TouchableOpacity>
<View>
<Text style={styles.item}>{item.title}</Text>
</View>
<View style={styles.divider}> </View>
</TouchableOpacity>
</View>
))}
</ScrollView>
) : (
<ScrollView showsVerticalScrollIndicator={false}>
{businessData.map((item, index) => (
<View key={index}>
<TouchableOpacity>
<View>
<Text style={styles.item}>{item.title}</Text>
</View>
<View style={styles.divider}> </View>
</TouchableOpacity>
</View>
))}
</ScrollView>
)}
</View>
)
}
export default LoansScreen;
const styles = StyleSheet.create({
divider: {
width: "100%",
height: 1,
backgroundColor: "black",
marginTop: 1,
opacity: 0.1,
shadowOpacity: 10,
},
item: {
marginHorizontal: 20,
fontSize: 14,
fontWeight: "400",
padding: 13,
alignContent: "center",
},
heading: {
fontSize: 16,
fontWeight: "500",
},
});
CodePudding user response:
The issue lies in the following line of code:
<View style={styles.divider}> </View>
In the above, you are rendering a View
with no children. However, it contains a space. A space is text. it is now allowed to render text in non-text components.
There are several improvements that we can make to your code as well. First, it is not necessary to use two ScrollView
s. We can just use one and conditionally render its content. You are using a boolean state to toggle between the two different lists. Why not use the data as the state instead and toggle between the two data arrays?
Furthermore, since your data arrays are static, you should define them outside of the component.
Here is an updated version of your code with the mentioned improvements.
import {
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import React, { useState } from 'react';
const retailData = [
{
id: 1,
title: 'Personal Loan',
},
{
id: 2,
title: 'Home Loan',
},
{
id: 3,
title: 'Car Loan',
},
{
id: 4,
title: 'Agri & Rural Loan',
},
{
id: 5,
title: 'Instant Car Loan Top Up',
},
{
id: 6,
title: 'Loan Against Property',
},
{
id: 7,
title: 'Loan Against Fixed Deposit',
},
{
id: 8,
title: 'Education Loan - Higher Studies',
},
{
id: 9,
title: 'Two Wheeler Loans',
},
{
id: 10,
title: '24x7 Loan Against Securities',
},
];
const businessData = [
{
id: 101,
title: 'Business Loan',
},
{
id: 102,
title: 'Doctor Loan',
},
{
id: 103,
title: 'Cash Credit',
},
{
id: 104,
title: 'Overdraft',
},
{
id: 105,
title: 'Overdraft Renewal',
},
{
id: 106,
title: 'Secured Term Loan',
},
{
id: 107,
title: 'Merchant Loan',
},
{
id: 108,
title: 'Trade Finance',
},
{
id: 109,
title: 'Digital Business Loan',
},
];
export default function App() {
const [retail, setRetail] = useState(retailData);
return (
<View>
<View style={[styles.divider, { marginTop: 2 }]}></View>
<View
style={{
alignItems: 'flex-start',
justifyContent: 'space-evenly',
flexDirection: 'row',
padding: 10,
}}>
<TouchableOpacity onPress={() => setRetail(retailData)}>
<Text style={styles.heading}> Retail </Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => setRetail(businessData)}>
<Text style={styles.heading}>Business</Text>
</TouchableOpacity>
</View>
<View style={[styles.divider, { marginBottom: 10 }]}></View>
<ScrollView showsVerticalScrollIndicator={false}>
{retail.map((item, index) => (
<View key={index}>
<TouchableOpacity>
<View>
<Text style={styles.item}>{item.title}</Text>
</View>
<View style={styles.divider}></View>
</TouchableOpacity>
</View>
))}
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
divider: {
width: '100%',
height: 1,
backgroundColor: 'black',
marginTop: 1,
opacity: 0.1,
shadowOpacity: 10,
},
item: {
marginHorizontal: 20,
fontSize: 14,
fontWeight: '400',
padding: 13,
alignContent: 'center',
},
heading: {
fontSize: 16,
fontWeight: '500',
},
});