Вопрос или проблема
Я отображаю данные, полученные из API, в таблице, которая содержит поля ввода для редактирования данных.
В ней есть несколько записей данных, полученных через API, после изменения записи я хочу обновить изменения, внесенные пользователем, и передать их в API для обновления.
{Result.map((item,index) => (
<tr key={index} className="table-Result-Data">
<td>
<input
type="text"
name="applicationId"
value={item.acd_ap_id}
readOnly
/>
</td>
<td>
<input
type="text"
name="applicationName"
value={item.acd_ap_nm}
readOnly
/>
</td>
<td>
<input
type="text"
name="gsid"
value={item.acd_ap_gsid}
readOnly
/>
</td>
<td>
<input
type="text"
name="Sequence"
value={item.acd_con_seq}
readOnly
/>
</td>
<td>
<input
type="text"
name="applicationDl"
onChange={(e) => {
item.acd_appl_dl = e.target.value;
}}
defaultValue={item.acd_appl_dl}
/>
</td>
<td>
<input
type="email"
name="leadManagerDl"
defaultValue={item.acd_lead_manager_dl}
onChange={(e) => {
item.acd_lead_manager_dl = e.target.value;
}}
/>
</td>
<td>
<input
type="email"
name="systemOwnerNameDl"
defaultValue={item.acd_system_owner_name_dl}
onChange={(e) => {
item.acd_system_owner_name_dl = e.target.value;
}}
/>
</td>
<td>
<input
type="text"
name="dataCenterName"
defaultValue={item.acd_dc_name}
onChange={(e) => {
item.acd_dc_name = e.target.value;
}}
/>
</td>
<td>
<input
type="text"
name="qaSftpId"
defaultValue={item.acd_qa_sftp_id}
onChange={(e) => {
item.acd_qa_sftp_id = e.target.value;
}}
/>
</td>
<td>
<input
type="text"
name="qaSftpPwd"
defaultValue={item.acd_qa_sftp_pwd}
onChange={(e) => {
item.acd_qa_sftp_pwd = e.target.value;
}}
/>
</td>
<td>
<input
type="text"
name="prodSftpId"
defaultValue={item.acd_prod_sftp_id}
onChange={(e) => {
item.acd_prod_sftp_id = e.target.value;
}}
/>
</td>
<td>
<input
type="text"
name="prodSftpPwd"
defaultValue={item.acd_prod_sftp_pwd}
onChange={(e) => {
item.acd_prod_sftp_pwd = e.target.value;
}}
/>
</td>
<td>
<input
type="text"
name="updatedUser"
defaultValue={item.acd_upd_usr}
onChange={(e) => {
item.acd_upd_usr = e.target.value;
}}
/>
</td>
</tr>
))}
</tbody>
</table>
</div>
<input type="submit" className="submit_Update" />
Результат имеет четыре данных, к которым я обращаюсь, используя formdata
export async function action({ request }) {
console.log("Функция APDB вызвана");
const formData = await request.formData();
console.log(formData)
const data = Object.fromEntries(formData);
console.log(data)
}
Когда я отправляю, я получаю только последние значения результатов, а не все объекты результатов. Это связано с функцией map или с чем-то еще? Как я могу это решить?
Ответ или решение
Чтобы понять, почему при отправке формы вы получаете только последние значения из массива объектов, а не все данные, давайте подробно проанализируем вашу проблему и предложим рекомендации по ее решению.
Проблема
Вы отображаете данные, полученные из API, в таблице, где каждый объект из массива Result
рендерится в строке таблицы. При изменении значений в полях ввода вы пытаетесь сохранить изменения в этих объектах. Однако при отправке данных с помощью formData
вы получаете только последние значения, что указывает на наличие проблемы в вашем подходе к обработке данных.
Когда вы используете метод Object.fromEntries(formData)
, вы извлекаете данные из формы и конвертируете их в объект. Однако при этом вы не учитываете, что имена полей (атрибут name
у ваших элементов ввода) одинаковы для всех объектов, и поэтому при каждом новом значении поле name
перезаписывается, оставляя в итоге только последнее значение.
Решение
Чтобы решить эту проблему, необходимо сделать два изменения:
- Изменение имени полей ввода: Для каждого поля ввода необходимо задать уникальное имя, которое будет включать индекс строки. Это позволит вам собирать данные для каждого объекта отдельно.
{Result.map((item, index) => (
<tr key={index} className="table-Result-Data">
{/* Другие поля */}
<td>
<input
type="text"
name={`applicationDl[${index}]`} // Уникальное имя
onChange={(e) => {
item.acd_appl_dl = e.target.value;
}}
defaultValue={item.acd_appl_dl}
/>
</td>
{/* Повторить это для всех полей ввода */}
</tr>
))}
Используя этот подход, вы получите массив значений для каждого поля при следующем извлечении данных из formData
.
- Обработка данных на серверной стороне: При обработке данных после отправки формы вам также потребуется адаптировать код, чтобы извлекать массивы значений с правильным индексом.
export async function action({ request }) {
const formData = await request.formData();
const data = {};
for (const [key, value] of formData.entries()) {
if (!data[key]) {
data[key] = [];
}
data[key].push(value); // Сохраняем значения в массив
}
console.log(data); // Теперь у вас будет объект с массивами значений
}
Заключение
Таким образом, при изменении имен полей ввода, чтобы они были уникальны для каждого объекта, и корректировке способа извлечения данных на сервере, вы сможете успешно собрать данные из всех строк таблицы. Этот подход поможет вам избежать перезаписи значений и гарантировать, что вы получите полные и актуальные данные для обновления через API.
Эти рекомендации позволят вам улучшить структуру вашего кода и обеспечить корректную работу вашего интерфейса.