Reputation: 177
I have the below array of objects:
const [rows, setRows] = useState([
{id: 1, key: "key1", value: "value1"},
{id: 2, key: "key2", value: "value2"}
]);
And I have the below inputs as well:
<TextField name="key" onChange={(e)=> handleTable(e, record.id)} value{rows.filter...}/>
<TextField name="value" onChange={(e)=> handleTable(e, record.id)} value{rows.filter...}/>
Now I know that for handling the above inputs I should loop to find the appropriate object based on its ID then try to update it, I need one another for loop for the value of the above inputs as well, but that takes a long time in terms of hooks and reloading each time the user enters something, how can I handle the above situation, both updating and showing the appropriate item in the array?
Upvotes: 3
Views: 4707
Reputation: 45
const [rows, setRows] = useState([
{ id: 1, key: "key1", value: "value1" },
{ id: 2, key: "key2", value: "value2" }
]);
const handleTable = (e, id) => {
const newRows = [...rows]; //spread the rows array into a new array
const index = rows.find((item, i) => {
if (item.id === id) return i;
}); //found the index using the id
if (e.target.name === "key") {
newRows[index].key = e.target.value; // update using the index
} else {
newRows[index].value = e.target.value;
}
setRows(() => [...newRows]);
};
<TextField name="key" onChange={(e)=> handleTable(e, record.id)} value{rows.filter...}/>
<TextField name="value" onChange={(e)=> handleTable(e, record.id)} value{rows.filter...}/>
Upvotes: 2
Reputation: 96
if there is a better way plz edit
const [value , setValue]=useState([])
in html :
*need separate state for each input elements
<input value={value[key] ? value[key] : ""} onChange={(e) => handleSetValue(e.target.value, key)}/>
set value func() :
function handleSetValue(e, key) {
setValue(s => {
const newArr = s.slice();
newArr[key] = e;
return newArr;
});
}
Upvotes: 0
Reputation: 51
Yes, you need to loop the textfields and pass the index to the change handler.
const [rows, setRows] = React.useState([
{ id: 1, key: "key1", value: "value1" },
{ id: 2, key: "key2", value: "value2" }
]);
const handleChange = (e,idx) => {
clone = [...rows];
let obj = clone[idx];
obj.value = e.target.value;
clone[idx] = obj;
setRows([...clone])
}
and Then you need to loop your rows with text field.
{ rows?.map((row, index) =>
<TextField value={rows[index]?.value} onChange={(e) =>
handleChange(e,index)} />
)}
This may help you to tweak your solution.
Upvotes: 2