Estoy creando un componente de formulario dinámico que toma información del usuario y la almacena en formato JSON y luego crea un formulario para el usuario final. Tengo que agregar valores dinámicamente para seleccionar las opciones de etiquetas, pero aparece un error TypeError: data.emplist no es iterable
const addNewEmp=()=>{ 61 | setEmpList((data)=>({ 62 | inputValue: '', > 63 | emplist: [ | ^ 64 | ...data.emplist, 65 | { 66 | empName: data.inputValueHe hecho varios cambios, pero no puedo averiguar qué está mal. Mi código a continuación
import React, { useState } from 'react' const Select = () => { const [inputValue,setInputValue] = useState('') const [emplist, setEmpList] = useState([ { empName: '---Select---' } ]); const addNewEmp=()=>{ setEmpList((data)=>({ inputValue: '', emplist: [ ...data.emplist, { empName: data.inputValue } ] })) } let empRecords = emplist.map((data) => { return <option>{data.empName}</option>; }); return ( <> <input type="text" placeholder="add options" onChange={(e)=> setInputValue(e.target.value)} /> <button onClick={addNewEmp}>Add +</button> <br /> <select>{empRecords}</select> {inputValue} </> ); } export default SelectSu función addEmpList está anulando el valor anterior de su empList que comenzó como una Array con un Object . Esta es la razón por la que recibe este error porque después de agregar un nuevo elemento, ya no puede iterar sobre él, ya que el Object no tiene una definición de Symbol.iterator como lo hace Array . Lo que significa que no puede iterar sobre un objeto.
Si desea agregar dinámicamente un nuevo elemento a una selección en React como se indica en su pregunta, debe almacenar el resultado de su cambio de entrada en un estado, y cuando lo necesite (como un envío de formulario), puede agregar esto elemento en una matriz de elementos que contendrán las opciones dinámicas que React representará cada vez que cambie este estado.
import React, {useState, useCallback} from "react"; const Select = () => { const [options, setOptions] = useState([]); const [text, setText] = useState(""); const [value, setValue] = useState(""); const handleTextChange = useCallback(changeEvent => { setText(changeEvent.currentTarget.value); }, [setText]); const handleValueChange = useCallback(changeEvent => { setValue(changeEvent.currentTarget.value); }, [setValue]); const handleSubmit = useCallback(submitEvent => { submitEvent.preventDefault(); setOptions([ ...options, { key: window.crypto.randomUUID(), text, value } ]); }, [text, value, options, setOptions]); return ( <> <form onSubmit={handleSubmit}> <div> <label htmlFor="text"> Text </label> <input id="text" type="text" value={text} onChange={handleTextChange} /> </div> <div> <label htmlFor="value"> Value </label> <input id="value" type="text" value={value} onChange={handleValueChange} /> </div> <button type="submit"> Add </button> </form> <select> {options.map(currentOption => ( <option key={currentOption.key} value={currentOption.value}> {currentOption.text} </option> ))} </select> </> ); }; export default Select;No es necesario escribir data.emplist o data.inputValue , puede acceder directamente a esas cosas
setEmpList((data)=>({ inputValue: '', emplist: [ ...emplist, { empName: inputValue } ] }))Responder
import React, {useState } from "react"; const Select = () => { const [inputValue, setInputValue] = useState(""); const [emplist, setEmpList] = useState([]); let empRecords = emplist.length > 0 && emplist.map((data) => { return ( <option value={data.empName} key={data.empName}> {data.empName} </option> ); }); const addNewEmp = () => { const addItems = { empName: inputValue, value: inputValue, }; const addEmp = [...emplist]; addEmp.push(addItems); setEmpList(addEmp); }; return ( <> <input type="text" placeholder="add options" onChange={(e)=> setInputValue(e.target.value)} /> <button onClick={addNewEmp}>Add +</button> <br /> <select>{empRecords}</select> {inputValue} </> ); }; export default Select;