Tengo dos componentes funcionales y desde el componente principal estoy creando un conjunto de controles dinámicamente. En función de cada elemento creado, quiero eliminarlos, pero cada vez que se elimina el último. Por ejemplo, tres filas creadas cuando elimino la segunda o la primera, la última se eliminaba.

Education.jsx

function Education(props) { const blankEdu = { id: 0, name: "", percentage: "", year: "" }; const [eduState, setEduState] = useState([{ ...blankEdu }]); const addEducation = () ={amp}gt; { setEduState([...eduState, { ...blankEdu }]); }; function handleRemove(index) { console.log(index); if (eduState.length != 1) { const updatedEdu = [...eduState]; updatedEdu.splice(index, 1); setEduState([...updatedEdu]); } } const handleEducationChange = (index, e, c) ={amp}gt; { const updatedEdu = [...eduState]; updatedEdu[index][c] = e.target.value; updatedEdu[index]["id"] = index; setEduState(updatedEdu); }; return ( {amp}lt;div{amp}gt; {amp}lt;div className="shadow p-3 mb-5 bg-white rounded"{amp}gt; Final Step: Education {amp}lt;/div{amp}gt; {eduState.map((val, idx) ={amp}gt; ( {amp}lt;div key={idx} {amp}gt; {amp}lt;EducationInput key={`edu-${idx}`} idx={idx} handleEducationChange={handleEducationChange} /{amp}gt; {eduState.length {amp}gt; 1 ? ( {amp}lt;Button variant="danger" onClick={() ={amp}gt; handleRemove(idx)}{amp}gt; Remove Course {amp}lt;/Button{amp}gt; ) : null} {amp}lt;/div{amp}gt; ))} {amp}lt;Button variant="outline-info" onClick={addEducation}{amp}gt; Add New Degree {amp}lt;/Button{amp}gt; {amp}lt;/div{amp}gt; ); } export default Education; 

EducationInput.jsx

 const EducationInput = ({ idx, handleEducationChange }) ={amp}gt; { return ( {amp}lt;div key={`edu-${idx}`} id={`edu-${idx}`}{amp}gt; {amp}lt;span className="border border-success"{amp}gt; {amp}lt;Form{amp}gt; {amp}lt;Form.Group as={Row}{amp}gt; {amp}lt;Form.Label column sm={3}{amp}gt; {`Course #${idx   1}`}: {amp}lt;/Form.Label{amp}gt; {amp}lt;Col sm={5}{amp}gt; {amp}lt;input type="text" onChange={e ={amp}gt; handleEducationChange(idx, e, "name")} /{amp}gt; {amp}lt;/Col{amp}gt; {amp}lt;/Form.Group{amp}gt; {amp}lt;Form.Group as={Row}{amp}gt; {amp}lt;Form.Label column sm={3}{amp}gt; Passing Year: {amp}lt;/Form.Label{amp}gt; {amp}lt;Col sm={5}{amp}gt; {amp}lt;input type="text" onChange={e ={amp}gt; handleEducationChange(idx, e, "year")} /{amp}gt; {amp}lt;/Col{amp}gt; {amp}lt;/Form.Group{amp}gt; {amp}lt;/Form{amp}gt; {amp}lt;/span{amp}gt; {amp}lt;/div{amp}gt; ); }; export default EducationInput; 

Verifiqué y verifiqué el valor de updatedEdu imprimiendo en la consola. Está dando una salida correcta en la consola pero la función setEduState no se actualiza correctamente en la interfaz de usuario, no sé por qué.

Ritesh Gupta

es un nuevo contribuyente a este sitio. Tenga cuidado al pedir aclaraciones, comentarios y respuestas. Mira nuestro

Código de Conducta

.

Depende del índice del elemento, pero los índices cambian cuando agrega o elimina elementos, por lo que no son confiables.

Debe generar una identificación única automática al crear una nueva educación. Por ejemplo, el paquete uuid es popular para esta tarea.

Refactoré tu código un poco para que funcione:

Educación:

 import React, { useState } from "react"; import EducationInput from "./EducationInput"; import Button from "react-bootstrap/Button"; import uuidv4 from "uuid/v4"; function Education(props) { const blankEdu = { id: "", name: "", percentage: "", year: "" }; const [eduState, setEduState] = useState([{ ...blankEdu }]); const addEducation = () ={amp}gt; { setEduState([...eduState, { ...blankEdu, id: uuidv4() }]); }; function handleRemove(id) { console.log(id); if (eduState.length {amp}gt; 1) { const updatedEdus = eduState.filter(edu ={amp}gt; edu.id !== id); setEduState(updatedEdus); } } const handleEducationChange = (id, field, value) ={amp}gt; { console.log(field, value); let updatedEducations = eduState.map(edu ={amp}gt; { if (edu.id === id) return edu; edu[field] = value; return edu; }); setEduState(updatedEducations); }; return ( {amp}lt;div{amp}gt; {amp}lt;div className="shadow p-3 mb-5 bg-white rounded"{amp}gt; Final Step: Education {amp}lt;/div{amp}gt; {eduState.map(val ={amp}gt; ( {amp}lt;div key={val.id}{amp}gt; {amp}lt;EducationInput key={`edu-${val.id}`} idx={val.id} handleEducationChange={handleEducationChange} /{amp}gt; {eduState.length {amp}gt; 1 ? ( {amp}lt;Button variant="danger" onClick={() ={amp}gt; handleRemove(val.id)}{amp}gt; Remove Course {amp}lt;/Button{amp}gt; ) : null} {amp}lt;/div{amp}gt; ))} {amp}lt;Button variant="outline-info" onClick={addEducation}{amp}gt; Add New Degree {amp}lt;/Button{amp}gt; {amp}lt;br /{amp}gt; {amp}lt;br /{amp}gt; Educations in json:{JSON.stringify(eduState)} {amp}lt;/div{amp}gt; ); } export default Education; 

EducationInput

 import React from "react"; import Form from "react-bootstrap/Form"; import Col from "react-bootstrap/Col"; import Row from "react-bootstrap/Row"; const EducationInput = ({ idx, handleEducationChange }) ={amp}gt; { return ( {amp}lt;div key={`edu-${idx}`} id={`edu-${idx}`}{amp}gt; {amp}lt;span className="border border-success"{amp}gt; {amp}lt;Form{amp}gt; {amp}lt;Form.Group as={Row}{amp}gt; {amp}lt;Form.Label column sm={3}{amp}gt; {`Course #${idx   1}`}: {amp}lt;/Form.Label{amp}gt; {amp}lt;Col sm={5}{amp}gt; {amp}lt;input type="text" name="name" onChange={e ={amp}gt; handleEducationChange(idx, e.target.name, e.target.value) } /{amp}gt; {amp}lt;/Col{amp}gt; {amp}lt;/Form.Group{amp}gt; {amp}lt;Form.Group as={Row}{amp}gt; {amp}lt;Form.Label column sm={3}{amp}gt; Passing Year: {amp}lt;/Form.Label{amp}gt; {amp}lt;Col sm={5}{amp}gt; {amp}lt;input type="text" name="year" onChange={e ={amp}gt; handleEducationChange(idx, e.target.name, e.target.value) } /{amp}gt; {amp}lt;/Col{amp}gt; {amp}lt;/Form.Group{amp}gt; {amp}lt;/Form{amp}gt; {amp}lt;/span{amp}gt; {amp}lt;/div{amp}gt; ); }; export default EducationInput; 

Códigos y caja