Kash
Kash

Reputation: 1791

renderRows how to get value of last item

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

Answers (2)

Milore
Milore

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

VilleKoo
VilleKoo

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

Related Questions