Estoy tratando de mapear a través de una API y hacer que cada uno de sus objetos tenga datos expandibles. Sin embargo, cuando expando un div para un objeto, en lugar de expandir solo ese div en particular, expande todos mis objetos. ¿Cómo lo hice para que solo amplíe los datos de un objeto? Aquí está mi código:
export default function StudentsList({ students }) { const [isCollapsed, setIsCollapsed] = useState(true); const handleCollapse = () => { setIsCollapsed((prev) => !prev); }; return ( <div className={studentsBox}> {students.map((student) => ( <div className={card} key={student.id}> <div className={plus} onClick={handleCollapse} > {isCollapsed ? '+' : '-'} </div> <div className={isCollapsed ? collapse : ''}> <p>Test 1: {student.grades[0]}%</p> <p>Test 2: {student.grades[1]}%</p> <p>Test 3: {student.grades[2]}%</p> <p>Test 4: {student.grades[3]}%</p> <p>Test 5: {student.grades[4]}%</p> <p>Test 6: {student.grades[5]}%</p> <p>Test 7: {student.grades[6]}%</p> <p>Test 8: {student.grades[7]}%</p> </div> </div> </div> ))} ); }puedes hacer algo como esto
export default function StudentsList({ students }) { const [collapsed, setCollapsed] = useState(null); const handleCollapse = (id) => { setCollapsed(prev => prev === id? null : id); }; return ( <div className={studentsBox}> {students.map((student) => ( <div className={card} key={student.id}> <div className={plus} onClick={() => handleCollapse(student.id)} onMouseMove={() => setId(`${student.id}`)} > {collapsed === student.id ? '+' : '-'} </div> <div className={collapsed === student.id ? collapse : ''}> <p>Test 1: {student.grades[0]}%</p> <p>Test 2: {student.grades[1]}%</p> <p>Test 3: {student.grades[2]}%</p> <p>Test 4: {student.grades[3]}%</p> <p>Test 5: {student.grades[4]}%</p> <p>Test 6: {student.grades[5]}%</p> <p>Test 7: {student.grades[6]}%</p> <p>Test 8: {student.grades[7]}%</p> </div> </div> </div> ))} ); }Primero declaras el ID seleccionado
const [selectedId, setSelectedId] = useState(null);Luego configure onClick para establecerSelectedId
onClick={()=>setSelectedId(student.id)}De esta manera, puede cambiar la base className en el ID seleccionado
<div className={student.id !== selectedId ? collapse : ''}> <p>Test 1: {student.grades[0]}%</p> <p>Test 2: {student.grades[1]}%</p> .... </div>La belleza de React es hacer uso de muchos componentes. Use componentes adicionales para agregar algo de estructura a su presentación de sus datos.
StudentList (muestra una lista de...)Student (que, a su vez, muestra una lista de...)StudentGradeCada estudiante puede colapsarse fácilmente independientemente de la lista de estudiantes.
function StudentGrade({ grade, index }) { return <p>Test {index}: {grade}</p> } function Student({ student }) { const [isCollapsed, setIsCollapsed] = React.useState(true); const handleCollapse = () => { setIsCollapsed((prev) => !prev); }; return ( <div> <div onClick={handleCollapse}> {isCollapsed ? '-' : '+'} <span>{student.name}</span> </div> {!isCollapsed?null:( <div> {student.grades.map((grade, index) => ( <StudentGrade key={index} grade={grade} index={index}/> ))} </div> )} </div> ) } function StudentsList({ students }) { return ( <div> {students.map((student) => ( <Student key={student.id} student={student} /> ))} </div> ); } const students = [ { id: 1, name: 'Ann', grades: ['A', 'B'] }, { id: 2, name: 'Bob', grades: ['B', 'C'] }, { id: 3, name: 'Charlie', grades: ['C', 'D'] }, ] ReactDOM.render(<StudentsList students={students} />, document.getElementById('root')); <script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script> </script> <div id="root"></div>