I am making a dynamic form component which takes input from the user and stores it in JSON format and then creates a form for the end-user. I have to dynamically add values to select tag options but one error is coming TypeError: data.emplist is not iterable
const addNewEmp=()=>{
61 | setEmpList((data)=>({
62 | inputValue: '',
> 63 | emplist: [
| ^ 64 | ...data.emplist,
65 | {
66 | empName: data.inputValue
I have done several changes but cant figure out whats wrong. My code Below
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 Select
CodePudding user response:
No need to write data.emplist
or data.inputValue
, you can directly access those things
setEmpList((data)=>({
inputValue: '',
emplist: [
...emplist,
{
empName: inputValue
}
]
}))
CodePudding user response:
You addEmpList
function is overriding the old value of your empList
which started as an Array
with an Object
. This is why you are getting this error because after you add a new item you cannot iterate over it anymore since Object
do not have a definition of the Symbol.iterator
as the Array
does. Meaning you cannot iterate over an object.
If you want to dynamically add a new item to a select in React as stated in your question, you should be storing the result of your input change in a state, and whenever you need to (like a form submit), you can add this item in an array of items that will contain the dynamic options that will get rendered by React whenever this state change.
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;