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>
);