1

The Problem:

This is how the App is supposed to render the contacts, organized by sections according to their first name letters - A,B,C... So far i couldn't figure a way to diplay them in this way from A to Z. Neither changing the JSON structure or in ReactJS solved it. Every attempt to add more properties in the JSON, faced the limitation of Array.map one time "scaning". Any help is appreciated!

desired app

This is the JSON behind it:

[
    {
        "id": 1,
        "fname": "Amanda",
        "lname": "Gonzales",
        "contact": "(31) 9 9580-2530",
    },
    {
        "id": 2,
        "fname": "Astrid",
        "lname": "Guzman",
        "contact": "(31) 9 9790-2530",
    },
    {
        "id": 3,
        "fname": "Aurora",
        "lname": "Muñoz",
        "contact": "(57) 9 9580-2530",
    },
  
]

And the React JS as well:

class ShowContactsList extends Component {
    render() {
        const mappedJSON = mockData.map((inputMap, index) => (
            <ContactListOneContact
                key={index}
                lname={inputMap.lname}
                fname={inputMap.fname}
                fname={inputMap.fname}
                contact={inputMap.contact}
            />
        ));
        return (
            <div style={{ backgroundColor: 'yellow', width: '80%' }}>
                <h1>A</h1>
                {mappedJSON}
            </div>
        )
    }
}
2
  • Each time when you iterate over mockData whole component rerenders, endless loop may occur. Try to console.log(mappedJson) and see what it returns. Move this mapping function to somewhere else, as class function or best refactor component to functional component. Commented Nov 3, 2020 at 0:45
  • 2
    Just a heads up: The selected solution assumes the data is already presorted by last name. If it's unsorted, then it will just group by the last name as it appears in the structure. To make sure it's sorted, you can use sort with localeCompare: demo Commented Nov 3, 2020 at 1:56

1 Answer 1

1

You could create a group by letter, for your contacts, and then you iterate over the letters and for each letter, iterate over the contacts

    export default class ShowContactsList extends Component {
      render() {
        const groupedByLetter = mockData.reduce((groups, contact) => {
          const letter = contact.fname[0].toUpperCase();
          const group = groups[letter] || [];
          group.push(contact);
          groups[letter] = group;
          return groups;
        }, {});
    
        return Object.entries(groupedByLetter).map(([letter, contacts]) => {
          return (
            <div style={{ backgroundColor: "yellow", width: "80%" }}>
              <h1>{letter}</h1>
              {contacts.map((inputMap, index) => (
                <ContactListOneContact
                  key={index}
                  lname={inputMap.lname}
                  fname={inputMap.fname}
                  contact={inputMap.contact}
                />
              ))}
            </div>
          );
        });
      }
    }

Demo at https://codesandbox.io/s/twilight-cdn-e4tgs?file=/src/App.js

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.