I included an Icon while mapping an array and I need to change the icon on that specific iteration on when clicked, I also want to render the test results when the icon is clicked.
I'm not sure how to get a unique value that is specific to this iteration that will handle this change or I've my structure is all wrong how should I handle this?
const Students = ({students}) => {
return (
{students.map((student, i) => (
<div className="wrapper" key={student.id}>
<div className="img-container">
<img src={student.pic} alt="student" />
</div>
<div className="content">
<h1>
{student.firstName.toUpperCase()} {student.lastName.toUpperCase()}
</h1>
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p>Skill: {student.skill}</p>
<p>Average: {averageGrade(student.grades)}%</p>
{faMinus && <TestResults results={student.tests} />}
</div>
<FontAwesomeIcon
id={i}
onClick={e => handleTests(e.target.id)}
className="faIcon"
icon={current ? faPlus : faMinus}
/>
</div>
))}
)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Thanks ahead of time for any suggestions
CodePudding user response:
The return must always have a top-level tag.
const Students = ({ students }) => {
return (
<>
{students.map((student, i) => (
<div className="wrapper" key={student.id}>
<div className="img-container">
<img src={student.pic} alt="student" />
</div>
<div className="content">
<h1>
{student.firstName.toUpperCase()}{" "}
{student.lastName.toUpperCase()}
</h1>
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p>Skill: {student.skill}</p>
<p>Average: {averageGrade(student.grades)}%</p>
{faMinus && <TestResults results={student.tests} />}
</div>
<FontAwesomeIcon
id={i}
onClick={(e) => handleTests(e.target.id)}
className="faIcon"
icon={current ? faPlus : faMinus}
/>
</div>
))}
</>
);
};
CodePudding user response:
Let me know if this is what you're thinking. Just store the index in a state variable and compare against it. When they click change the index to the one they clicked on.
const Students = ({students}) => {
const [selectedIndex, setSelectedIndex] = useState(0)
function handleTests(id, index) { //NEW
//Your current code
setSelectedIndex(index) //NEW
}
return (
{students.map((student, i) => (
<div className="wrapper" key={student.id}>
<div className="img-container">
<img src={student.pic} alt="student" />
</div>
<div className="content">
<h1>
{student.firstName.toUpperCase()} {student.lastName.toUpperCase()}
</h1>
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p>Skill: {student.skill}</p>
<p>Average: {averageGrade(student.grades)}%</p>
{selectedIndex == i && <TestResults results={student.tests} />} //NEW
</div>
<FontAwesomeIcon
id={i}
onClick={e => handleTests(e.target.id, i)} //NEW
className="faIcon"
icon={selectedIndex == i ? faPlus : faMinus}
/>
</div>
))}
)
}