skip to Main Content

I want to create multiple Profile Cards in my React app, but I’m currently using repetitive code, which doesn’t seem efficient. I tried using a for loop, but it didn’t work as expected. How can I use a for loop or any other method to make my code more concise and efficient?

Current Code:

App.jsx:

import React from "react";
import Contacts from "../contacts";
import Card from "./Card.jsx";

function App(props) {
  return (
    <div>
      <h1 className="heading">My Contacts</h1>

      <Card
        name={Contacts[0].name}
        imgURL={Contacts[0].imgURL}
        phone={Contacts[0].phone}
        email={Contacts[0].email}
      />

      <Card
        name={Contacts[1].name}
        imgURL={Contacts[1].imgURL}
        phone={Contacts[1].phone}
        email={Contacts[1].email}
      />

      <Card
        name={Contacts[2].name}
        imgURL={Contacts[2].imgURL}
        phone={Contacts[2].phone}
        email={Contacts[2].email}
      />
    </div>
  );
}

export default App;

Contact Data (contacts.js):

const contacts = [
  {
    name: "Beyonce",
    imgURL:
      "https://blackhistorywall.files.wordpress.com/2010/02/picture-device-independent-bitmap-119.jpg",
    phone: "+123 456 789",
    email: "[email protected]",
  },
  {
    name: "Jack Bauer",
    imgURL:
      "https://pbs.twimg.com/profile_images/625247595825246208/X3XLea04_400x400.jpg",
    phone: "+987 654 321",
    email: "[email protected]",
  },
  {
    name: "Chuck Norris",
    imgURL:
      "https://i.pinimg.com/originals/e3/94/47/e39447de921955826b1e498ccf9a39af.png",
    phone: "+918 372 574",
    email: "[email protected]",
  },
];

export default contacts;

Card.jsx

import React from "react";
import Contact from "../contacts";

function Card(props) {
  return (
    <div>
      <div className="card">
        <div className="top">
          <h2 className="name">{props.name}</h2>
          <img src={props.imgURL} alt="avatar_img" className="circle-img" />
        </div>
        <div className="bottom">
          <p>{props.phone}</p>
          <p>{props.email}</p>
        </div>
      </div>
    </div>
  );
}

export default Card;

I want to reduce the repetition in the code above. How can I achieve this? Any suggestions for using a loop or another method to render the components more efficiently?

You can also check out the entire code here. 🙂

I tried using a for loop to dynamically create the components, but I couldn’t get it to work within the JSX. I expected the loop to iterate through my contacts array and render each contact as a separate component. However, my approach didn’t work as JSX doesn’t directly support for loops.

function App(props) {
  return (
    <div>
      <h1 className="heading">My Contacts</h1>
      {
        for (let i = 0; i < Contacts.length; i++) {
          <Card
            name={Contacts[i].name}
            imgURL={Contacts[i].imgURL}
            phone={Contacts[i].phone}
            email={Contacts[i].email}
          />
        }
      }
    </div>
  );
}

This code resulted in a syntax error because JSX does not support for loops directly. I need help finding a correct and efficient way to render multiple components without repetitive code.

2

Answers


  1. The shortes way is to use map() and then spread (...) the contact object to pass on all the props to the deeper component:

    {contacts.map(c => <Card {...c} />)}
    

    Demo with the above:

    const Example = () => {
    
        const contacts = [{name: "Beyonce", imgURL: "https://blackhistorywall.files.wordpress.com/2010/02/picture-device-independent-bitmap-119.jpg", phone: "+123 456 789", email: "[email protected]", }, {name: "Jack Bauer", imgURL: "https://pbs.twimg.com/profile_images/625247595825246208/X3XLea04_400x400.jpg", phone: "+987 654 321", email: "[email protected]", }, {name: "Chuck Norris", imgURL: "https://i.pinimg.com/originals/e3/94/47/e39447de921955826b1e498ccf9a39af.png", phone: "+918 372 574", email: "[email protected]", }, ];
    
        return (
            <div>
                <h1>{'Example'}</h1>
                {contacts.map(c => <Card {...c} />)}
            </div>
        )
    }
    
    const Card = (props) => {
      return (
        <div className="card">
          <div className="top">
            <h2 className="name">{props.name}</h2>
            <img src={props.imgURL} alt="avatar_img" className="circle-img" />
          </div>
          <div className="bottom">
            <p>{props.phone}</p>
            <p>{props.email}</p>
          </div>
        </div>
      );
    }
    ReactDOM.render(<Example />, document.getElementById("react"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="react"></div>
    Login or Signup to reply.
  2. You can use the map function for cases where you want to render the loop div or custom component. Please find the following codebase:

    export function App(props) {
      return (
        <div>
          <h1 className="heading">My Contacts</h1>
          {
            Contacts.map((_item) => 
              <Card
                name={_item?.name}
                imgURL={_item?.imgURL}
                phone={_item?.phone}
                email={_item?.email}
              />
            }
          }
        </div>
      );
    }
    

    —— OR use SPREAD expression, if the props are the same as the JSON object has——

    export function App(props) {
      return (
        <div>
          <h1 className="heading">My Contacts</h1>
          {
            Contacts.map((_item) => 
              <Card {..._item}/>
            }
          }
        </div>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search