Reputation: 1791
I am rendering data fetched from an api response. I want to be able to compare the current row being rendered with the last one.
Example: comparing item day with the last item. to be able to insert a separator of the day. this is just a simple example of what I am trying to do.
//data
const array = [
{day: '3/14', name: 'item1'},
{day: '3/14', name: 'item2'},
{day: '3/14', name: 'item3'},
{day: '3/15', name: 'item4'}
]
if new day, I will insert a separator. the intention is to group data by day.
let lastDay = null;
renderRows(item, index) {
//conditions
let day = item.day;
if(day != lastDay) daySeparator = true;
//store last day
lastDay = day;
return (
<ListItem noIndent style={style.listRow}>
<Row style={[style.tableRow,{alignItems: 'center'}]}>
<Text>{item.name}</Text>
</Row>
</ListItem>
);
}
My problem is that renderRows does not work like for loops, it render each item as separate without being able to keep track of previous rendered items.
is it possible to do it as so, or do I need to manipulate the array before passing it to RenderRows? if so, what's the most optimal way to do it, foreach? for loop?
Upvotes: 1
Views: 3478
Reputation: 1672
Now that your question is more clear I can suggest you to use something like <SectionList>
(see doc).
In order to use a SectionList
you have to pass it a sectioned array. With the data structure you posted I would group items by day:
const array = [
{ day: "3/14", name: "item1" },
{ day: "3/14", name: "item2" },
{ day: "3/14", name: "item3" },
{ day: "3/15", name: "item4" }
];
const grouped = array.reduce(
(result, item) => ({
...result,
[item["day"]]: [...(result[item["day"]] || []), item]
}),
{}
);
const sectionedList = Object.keys(grouped).map(item => ({
title: item,
data: grouped[item]
}));
Which will give you the following structure:
[
{
title: "3/14",
data: [
{ day: "3/14", name: "item1" },
{ day: "3/14", name: "item2" },
{ day: "3/14", name: "item3" }
]
},
{
title: "3/15",
data: [{ day: "3/15", name: "item4" }]
}
];
Now you can use it in a <SectionList>
, for example:
<SectionList
renderItem={({item, index, section}) => {...}}
renderSectionHeader={({section: {title}}) => (
<Text style={{fontWeight: 'bold'}}>{title}</Text>
)}
sections={sectionedList}
keyExtractor={(item, index) => item + index}
/>
This way you can properly customize everything.
I really hope this could help you!
Upvotes: 4
Reputation: 2854
One option is to make a new array with map from your initial array. Hope this will get you on the right direction :)
const array = [1, 2, 3, 4]
export default class App extends React.Component {
render() {
const newArr = array.map ((item, idx) => {
const newItem = idx === array.length - 1 ? 'Gotta keep them separated' : item
return <Text>{newItem}</Text>
})
return (
<View>
{newArr}
</View>
);
}
}
Here's a working expo snack
Upvotes: 1