Show 2 labels in FlatList React Native - react-native

I'm trying to render a flatlist that has 2 labels. I have done few options but nothing happened.
I want to show Title & Serial as Title & subtitle in each Item. If there is a solution really appreciated
Code:
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
Serial: '1254'
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Items',
Serial: '5678'
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
Serial: 'XXoX'
},
];
const Item = ({ title, Serial }) => (
<TouchableOpacity style={styles.ttListButton}>
<View style={styles.TTitem}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.title}>{Serial}</Text>
</View>
</TouchableOpacity>
);
render() {
const renderItem = ({ item }) => (
<Item title={item.title} />
);
return(
<View style={{backgroundColor: '#fff'}}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</View>
)

there is a typo in ({ title, Seria })
should be ({ title, Serial })
const renderItem = ({ item }) => (
<Item title={item.title} Serial={item.Serial} />
);

Related

React Native error Please report: Excessive number of pending callbacks: 501

I'm using react native I'm trying to create a category filter where it shows me the category list and once the category title is clicked it expends showing the sub-categories I keep getting the error Please report: Excessive number of pending callbacks: 501. Some pending callbacks that might have leaked by never being called from native code
**
This is my filter screen:**
...
const CategoryFilter = ( { route, navigation: { goBack } } ) => {
const navigation = useNavigation();
const {itemStore, itemCategory} = route.params;
const Touchable = Platform.OS === 'android' ? TouchableNativeFeedback : TouchableHighlight;
// use a map to keep track of collapsed state for each category
const [collapsed, setCollapsed] = useState(
dummyData.carouselData.reduce((map, category) => ({
...map,
[category.category]: false
}), {})
);
// helper function to toggle collapsed state for a given category
const toggleCollapsed = useCallback((category) => {
setCollapsed((prevCollapsed) => ({
...prevCollapsed,
[category]: !prevCollapsed[category],
}));
}, []);
// useRef to keep track of mounted status to avoid memory leaks
const isMounted = useRef(true);
useEffect(() => {
return () => {
isMounted.current = false;
};
}, []);
// debounce the toggleCollapsed function to prevent excessive callbacks
const debouncedToggleCollapsed = useDebounce(toggleCollapsed, 500, [
collapsed,
]);
return (
<SafeAreaView style={styles.container}>
<ScrollView>
<View style={styles.Header}>
<Touchable
style={styles.button}
onPress={() => goBack()}
activeOpacity={0.5} // Reduce the press delay on iOS
delayPressIn={0} // Remove the delay when pressing the button on Android
>
<Icon icon ='arrow-back-outline' color='#000' size={25}/>
</Touchable>
<Text style={{fontWeight: '800', fontSize: 20}}>Filter</Text>
</View >
<View style={styles.body}>
<View style={styles.section}>
<Text style={{fontSize: 20, fontWeight: '700'}}>Categories:</Text>
{dummyData.carouselData.map((category, index) => (
<View key={index}>
<Touchable
onPress={() => toggleCollapsed(category.category)}
activeOpacity={0.5}
delayPressIn={0}
>
<View>
<Text style={(category.category === itemCategory) ? styles.picked : styles.text}>
{category.category}
</Text>
</View>
</Touchable>
<View >
{collapsed[category.category] && isMounted.current && (
<View>
{category.subCategory.map((subItem) => (
<Text key={subItem.id} >{subItem.title}</Text>
))}
</View>
)}
</View>
</View>
))}
</View>
</View>
</ScrollView>
</SafeAreaView>
)
}
export default CategoryFilter
And this is the data I want to map thru in total I have 18 categories and each category contains too many sub-categories.. the collapse works fine, however, i keep getting the error and my app is really slow
const carouselData = [
{
image: "https://i.ibb.co/26VTJd3/BUBCAT-3-Bubcat-Bread-220208-1644346379881.png",
title: "Bakery",
subCategory: [
{title: 'All', id: 1, name: 'Bakery'},
{title: 'Bagels, Buns & Rolls', id: 2, name: 'Bakery, Bagels, Buns & Rolls', image: "https://i.ibb.co/8BrQH1d/pexels-anna-tarazevich-6937426.jpg"},
{title: 'Cakes & Desserts', id: 3, name: 'Bakery, Cakes & Desserts', image: "https://i.ibb.co/hK0N8Fm/pexels-11719204.jpg"},
{title: 'Bakery, Bread', id: 4, name: 'Bakery, Bread', image: "https://i.ibb.co/dbxtRKT/pexe"},
{title: 'Breakfast', id: 5, name: 'Bakery, Breakfast', image: "https://i.ibb.co/dbxtRKT/pexels-ash-376464.jpg"},
],
id: 1,
category:"Bakery"
},
]

FlatList inside SectionList

I have screen with 3 different Lists, all lists have some custom header/footer and Lists contain big amount of data, so my question is - is there any performance issue with FlatList inside of SectionList?
This is rough example what i want to do
const App = () => {
const renderItem = ({item, section, index}) => {
switch (section.type) {
case 'LIST_1':
return (
<View>
<Text>Some custom set of components</Text>
<FlatList
data={section.items}
renderItem={({item}) => (
<View
style={{
padding: 20,
margin: 10,
backgroundColor: 'blue',
}}>
<Text>{item.title}</Text>
</View>
)}
keyExtractor={item => item.id}
/>
</View>
);
case 'LIST_2':
return (
<View>
<Text>Some custom set of components</Text>
<FlatList
data={section.items}
renderItem={({item}) => (
<View
style={{
padding: 20,
margin: 10,
backgroundColor: 'red',
}}>
<Text>{item.count}</Text>
</View>
)}
keyExtractor={item => item.id}
/>
</View>
);
case 'LIST_3':
return (
<View>
<Text>Some custom set of components</Text>
<FlatList
data={section.items}
renderItem={({item}) => (
<View
style={{
padding: 20,
margin: 10,
backgroundColor: 'blue',
}}>
<Text>{item.score}</Text>
</View>
)}
keyExtractor={item => item.id}
/>
</View>
);
}
};
const sections = [
{
type: 'LIST_1',
data: [1],
items: Array.from(Array(50)).map((el, i) => ({
id: i + 1,
title: i + 1,
})),
},
{
type: 'LIST_2',
data: [2],
items: Array.from(Array(50)).map((el, i) => ({
id: i + 1,
count: i + 1,
})),
},
{
type: 'LIST_3',
data: [3],
items: Array.from(Array(50)).map((el, i) => ({
id: i + 1,
score: i + 1,
})),
},
];
return (
<SafeAreaView>
<SectionList
sections={sections}
keyExtractor={item => item}
renderItem={renderItem}
/>
</SafeAreaView>
);
};
If this is not optimal solution and ScrollView takes a lot of time to render, Can you guide me what is better?
Your example can be achieved simply by using SectionList.
// Here we define section objects. I arbitrarily added title, footer and style.
const DATA = [
{
title: 'Section 1 header',
footer: 'Section 1 footer',
data: [...Array(3).keys()],
style: { backgroundColor: 'red' },
},
{
title: 'Section 2 header',
footer: 'Section 2 footer',
data: [...Array(3).keys()],
style: { backgroundColor: 'blue' },
},
{
title: 'Section 3 header',
footer: 'Section 3 footer',
data: [...Array(3).keys()],
style: { backgroundColor: 'yellow' },
},
]
// renderItem gets passed an object with item, section, index and separator keys. I'm using item and section to access my own section style.
const Item = ({ item, sectionStyle }) => (
<View style={[styles.item, sectionStyle]}>
<Text style={styles.title}>{item}</Text>
</View>
)
// Use renderSectionHeader and renderSectionFooter props to add, respectively, header and footer.
const App = () => (
<SafeAreaView style={styles.container}>
<SectionList
sections={DATA}
keyExtractor={(item, index) => item + index}
renderItem={({ item, section }) => <Item item={item} sectionStyle={section.style} />}
renderSectionHeader={({ section: { title } }) => <Text style={styles.header}>{title}</Text>}
renderSectionFooter={({ section: { footer } }) => <Text style={styles.header}>{footer}</Text>}
/>
</SafeAreaView>
)
And to answer your original question, you might run into performance issues with react-natives list components, it depends on many factors, including your data and rendered components.
You can read more on the topic here:
https://reactnative.dev/docs/optimizing-flatlist-configuration

How can I add a search bar with a flat list in react native (no json)?

I am building an app, where I have a list and I would like to search the items in the list with a search input how can I do?
const videos = [
{name: 'Unity Pro', link:'https://www.youtube.com/watch?v=A7btOci5Gs4&t',key:'1'},
{name: 'video2', link:'https://www.youtube.com/watchv=K36nOkqjbso&ab_channel=AppleExplained',key:'2'},
{name: 'video3', link:'https://www.youtube.com/watch?v=A7btOci5Gs4&t',key:'3'},
]
const ListVideos = ({navigation}) => {
return(
(code....)
<FlatList data={videos}
renderItem={({ item }) => (
<TouchableOpacity style={styles.button} onPress={() => {Linking.openURL(item.link)}}>
<IonIcon name="open-outline" size={16} color="white" style={{justifyContent:"center", alignContent:'center', alignItems:"center", alignSelf:"center", paddingRight:10}}/>
<Text style={styles.inbuttonText} >{item.name}</Text>
</TouchableOpacity>
)}
>
</FlatList>
Use TextInput to filter your list. Set a state for your current variable and a data that will be filtered using your current input text. Something like this.
const [searchText, setSearchText] = useState();
//filtering
const searchFilteredData = searchText
? flatListData.filter((x) =>
x.<filterItem>.toLowerCase().includes(searchText.toLowerCase())
)
: flatListData;
Then, in your render for TextInput:
<TextInput
placeholder="Search..."
style={}
onChangeText={(text) => {
setSearchText(text);
}}
value={searchText}
/>
and your flatlist:
<FlatList
data={searchFilteredData}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
change filterItem based on your data structure. For example your data looks like this:
data = [
{
id: "1",
name: "John Smith",
},
{
id: "2",
name: "John Willow",
},
use x.name in the filter function.

FlatList renderItem returning undefined

i have a flatList that renders a component with some props, but the renderItem returns me 'undefined'. I´m new to react-native and I cant´t find a solution. Thanks
edit:
Is it possible that the styles I used in 'posts.js' may affect the flatList render?
Feed.js:
export default function Feed() {
const Posts = [
{ id: 1, title: "eu", photoDesc: 'eu' },
{ id: 2, title: "me", photoDesc: 'me' }
]
console.log;
return (
<FlatList
keyExtractor={props => props.id}
data={Posts}
renderItem={({ item }) => <FeedPosts title={`${item.title}`} photoDesc={`${item.photoDesc}`} ></FeedPosts>}
>
</FlatList>
);
}
Posts.js:
export default function FeedPosts(props) {
return (
<Container>
<Header>
<TouchableOpacity>
<FontAwesome5 name='bell' size={40} style={{ marginLeft: 10 }}></FontAwesome5>
</TouchableOpacity>
<TouchableOpacity>
<Ionicons name='add-circle' size={40} style={{ marginRight: 5 }}></Ionicons>
</TouchableOpacity>
</Header>
<Body>
<Time>15/12/2021 as 17:42pm</Time>
<User>
<Icon source={require('../../assets/vibe.jpg')}></Icon>
<Description>{props.title}</Description>
</User>
<Content>
<PetPhoto source={props.postImg}></PetPhoto>
</Content>
<ContentDesc >
<PhotoDesc> {props.photoDesc}</PhotoDesc>
</ContentDesc>
<Bottom>
<Comment title="Comment" placeholder="Escrever Comentário"></Comment>
</Bottom>
<Buttons></Buttons>
</Body>
</Container>
);
}
Your variable Posts contains an array of React components. Instead, it should contain an array of data that you transform into components.
So your Posts should look more like this:
const Posts = [
{title: "My title", photoDesc: "Desc"},
{title: "My title2", photoDesc: "Desc2"},
{title: "My title3", photoDesc: "Desc3"}
]
Here's an example (straight from the React Native documentation) of how this works in context:
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const App = () => {
const renderItem = ({ item }) => (
<Item title={item.title} />
);
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
(https://reactnative.dev/docs/flatlist)
You can see in the above example that DATA is an array of objects, which gets transformed with the function renderItem into components. Very similar to your use case.

Add colors dynamically to LinearGradient

I'm using using this data to fill a FlatList, each item contains a LinearGradient
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
firstColor: "#f472a7",
secondColor: "#d84351"
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
firstColor: "#50be71",
secondColor: "#50be71"
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
firstColor: "#e2bd4f",
secondColor: "#e49074"
}
];
I added two properties called "firstColor" and "secondColor", to fill the LinearGradient colors, but I'm having some issues doing that. I'm receiving this error:
TypeError: undefined is not an object (evaluating '_ref3.secondColor')
Code:
const Item = ({ title }, { firstColor }, { secondColor }) => (
<LinearGradient
colors={[{firstColor}, {secondColor} ]}
style={styles.item}
>
<Text style={styles.title}>{title}</Text>
</LinearGradient>
);
const renderItem = ({ item }) => (
<Item title={item.title} />
);
...
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</SafeAreaView>
Try this
const Item = ({ title, firstColor, secondColor}) => (
<LinearGradient
colors={[firstColor, secondColor ]}
style={styles.item}
>
<Text style={styles.title}>{title}</Text>
</LinearGradient>
);
const renderItem = ({ item}) => (
<Item
firstColor={item.firstColor }
secondColor={ item.secondColor }
title={item.title}
/>
);
const LinearGradient = ({ color, firstColor, secondColor }) => {
const colorArr = [firstColor, secondColor];
return (
<View>
<Text>{color}</Text>
<Text>{firstColor}</Text>
<Text>{secondColor}</Text>
</View>
);
};
can you try this, you were passing the data in the wrong way. I did some changes in similar example.