Home > Enterprise >  how to use map in react to create multiple component?
how to use map in react to create multiple component?

Time:09-25

I have this array that has this structure please check the code down below , my end results should look like the following :

  • veg
  • apple
  • carrot

  • meat
  • chicken
  • steak

my current results are

apple carrot chicken steak

since I cannot structure the array other wise and don't want to go in to deep nesting or even nest loops which I doubt it will work in react any idea how to achieve the previous results using map , where I map through group only once to create the group name and to then add the items related to that group inside that group?, food for thought : could conditional rendering be also leveraged here ? I was able to only get either the group multiple times or the items only..

const arr = {
  itmes: [
    { id: 1, group: "veg", item: "apple" },
    { id: 2, group: "veg", item: "carrot" },
    { id: 3, group: "meat", item: "chicken" },
    { id: 4, group: "meat", item: "steak" }
  ]
};

function App() {
  return (
    <div>
      {arr["itmes"].map(
        (item) => item.group
        //item.item
      )}
    </div>
  );
}

Edit vibrant-sky-jwrmf

CodePudding user response:

Option 1

First, make sure your array is sorted by Group:

const sorted = arr["itmes"]
    .sort((a, b) => (a.group || '').localeCompare(b.group));

Then you can render and conditionally add another heading element whenever the group name changes:

<ul>
    {data.map((d, id) => (
        <>
            ((id > 0 || d.group !== data[id - 1].group) ? <li key={`${id}-h`}><b>{d.group}</b></li> : undefined)
            <li key={`${id}-v`}>{d.item}</li>
        </>
    ))}
</ul>

Extra: Custom group sorting

If you need to custom sort the array according to another array:

const sortLtu = ['veg', 'apple', 'meat'];
data.sort((a, b) => sortLtu.indexOf(a.group) - sortLtu.indexOf(b.group));

Option 2: Util function

If you end u doing this often you may create a util function:

Array.prototype.groupBy = function(cb) {
    const groups = [];
    this.forEach((d, id, arr) => {
        const g = cb(d, id, arr);
        let group = groups.find(_g => _g.group === g);
        if (!group) {
            group = { group: g, items: [] };
            groups.push(group);
        }
        group.items.push(d);
    })
    return groups;
}

And then use it like

{data.groupBy(i => i.group).map((bundle, ix) => (
    <div key={ix}>
        <b>{bundle.group}</b>
        <ul>
            {bundle.items.map((item, ix) => <li key={ix}>{item.item}</li>)}
        </ul>
    </div>
))}
  • Related