i have a table where the table has many rows of data. enter image description here
my table has function which can add multiple row to handle multiple input. so far this function to add multiple rows in my table is works. when i click button to generate multiple empty rows. this is example code that i used before. this code just record lasted input.
const [newInputRows, setNewInputRows] = useState([])
const handleChangeNewRows = (event) => {
setNewRows({...newInputRows, [event.target.name] : event.target.value})
console.log(newInputRows)
}
this bellow part of return. this is my code to generate new empty rows::
const newRows = [0, 1, 2, 3, 4]
<tbody>
{
insertRows && newRows.map(rows =>
<tr key={rows} id={rows}>
<td style={setStyle("20px")}></td>
{
_header.map((column,idc) => column === '_id' ? null : <td key={idc} className="input"><InputRows type="text" name={column} onChange={handleChangeNewRows}/></td>)
}
</tr>
)
}
</tbody>
as you can see, all of the rows has multiple input with same(single) name. my question is how to handle form input with multiple values in a single input name. because this form will send into backend where the database has 2 field countryCode and Country name. i want to make this form send to backend to be an array of object like this bellow:
[
{countryCode: "A", countryName: "countryA"},
{countryCode: "B", countryName: "countryB"},
{countryCode: "C", countryName: "countryC"}
]
how to handle this in reactjs?
An issue I see is with how you handle updating row data, you are changing the state invariant from array to object and you've no way to uniquely identify the row of data you want to update.
I suggest first create a callback to add an id
to each row new data element.
import { v4 as uuidV4 } from "uuid";
...
const [rowData, setRowData] = useState([]);
const addRow = () =>
setRowData((rowData) =>
rowData.concat({
id: uuidV4(),
countryCode: "",
countryName: ""
})
);
Use a curried change handler to close over in scope a row id, and use a functional state update to shallow copy the previous state.
const changeHandler = (rowId) => (e) => {
const { name, value } = e.target;
setRowData((rowData) =>
rowData.map((data) =>
data.id === rowId
? {
...data,
[name]: value
}
: data
)
);
};
Map the row data and attach the change handlers.
{rowData.map((data) => (
<tr key={data.id}>
<td>
<input
name="countryCode"
value={data.countryCode}
onChange={changeHandler(data.id)}
/>
</td>
<td>
<input
name="countryName"
value={data.countryName}
onChange={changeHandler(data.id)}
/>
</td>
</tr>
))}
Demo
[ {countryCode: "A", countryName: "countryA"}, {countryCode: "B", countryName: "countryB"}, {countryCode: "C", countryName: "countryC"} ]