Home > Blockchain >  Unable to loop single react component
Unable to loop single react component

Time:04-19

I'm trying to loop my StudentInfo component so a blurb of information can be repeated down an array of 25 objects provided through an API for each object/a student (name, email, company, etc.) I'm not sure where I'm going wrong; here is my attempted loop via the map function:

export default function StudentList() {
  let students = useState(null);
  return (
    <div className="StudentList">
      <div className="row">
        <div className="col">
          {students.map(function (student, index) {
            if (index <= 25) {
              return (
                <div className="col" key={index}>
                  <StudentInfo data={student} />
                </div>
              );
            }
          })}
        </div>
      </div>
    </div>
  );
}

Can someone see what I'm missing or what I might have skipped? I usually assume that I must be doing something wrong because I'm still new at React and trying to adapt other code I used for a weather forecast app to be used for this, but I don't think it's translating over well.

When I run this, I see the first object twice, i.e. Name, Email, Company, etc. it shows the info for the same person twice, rather than the first person, the second person, etc. I want to be able to see this pull all the objects from the array.

Here is the information I'm pulling to return as an entry on student info:

export default function StudentInfo() {
  const [info, addInfo] = useState(" ");

  function setInfo(response) {
    addInfo({
      number: response.data.students[0].id,
      first: response.data.students[0].firstName,
      last: response.data.students[0].lastName,
      email: response.data.students[0].email,
      company: response.data.students[0].company,
      skill: response.data.students[0].skill,
      average: response.data.students[0].grades[0],
    });
  }

  let url = "https://api.hatchways.io/assessment/students";
  axios.get(url).then(setInfo);

  return (
    <div className="StudentInfo">
      <h1>{info.number}.</h1>
      <h2>
        Name: {info.first} {info.last}
      </h2>
      <h2>Email: {info.email}</h2>
      <h2>Company: {info.company}</h2>
      <h2>Skill: {info.skill}</h2>
      <h2>Average: {info.average}</h2>
    </div>
  );
}

I'm using "if (index <= 25)" as there are 25 total entries that I want showing, but as I mentioned, I have no doubt I'm going about this incorrectly. I want this to loop through all 25 objects with the above information, as I keep saying. I'm sorry if I'm not speaking technically enough to be understood, as I am still learning.

I just want this to return 25 times with info from each object so that it's all listed out.

This is what it currently looks like

CodePudding user response:

There are some errors in your code.

UseState

React useState hook returns an array with a value and a setter method to update the state useState docs.

const [students, setStudents] = useState(null);

Iterate over null values

If your state starts with a null value you will not be able to iterate over it. To avoid getting an error you should make sure to use the map operator when your state has a value.

{students && students.map(function (student, index) {
   ...
})}

Handling side effects

You should move your API request (and set your info state) inside of a useEffect (useEffect docs). This way you will set those values asynchronously after the component is mounted.

export default function StudentInfo() {
  const [info, addInfo] = useState(null);

  useEffect(() => {
    async function fetchInfo() {
      const url = "https://api.hatchways.io/assessment/students"; //should be a constant outside the component
      const response = await axios.get(url);
      addInfo({
        number: response.data.students[0].id,
        first: response.data.students[0].firstName,
        last: response.data.students[0].lastName,
        email: response.data.students[0].email,
        company: response.data.students[0].company,
        skill: response.data.students[0].skill,
        average: response.data.students[0].grades[0],
    });
    fetchInfo();
  }, [])

  return (
    <div className="StudentInfo">
     {info &&
      <h1>{info.number}.</h1>
      <h2>
        Name: {info.first} {info.last}
      </h2>
      <h2>Email: {info.email}</h2>
      <h2>Company: {info.company}</h2>
      <h2>Skill: {info.skill}</h2>
      <h2>Average: {info.average}</h2>
    }
    </div>
  );
}

CodePudding user response:

export default function StudentList() {
  const [students, setStudents] = useState([]);

Check React's documentation React.

Also check if it cannot be declared that way, you need to use a ternary if. Check that part in React's documenation Conditional rending

        {students.map(function (student, index) {
        index <= 25 && (
            <div className="col" key={index}>
              <StudentInfo data={student} />
            </div>
          );
        
  • Related