Im trying to create a table with an array of products, the problem I have is that the inputs take the value of any input with the same "name". Also, when I try to remove any of the products, it always removes the last one.
https://stackblitz.com/edit/react-gto9bw?file=src/App.js
const [producto, setProducto] = useState({
codigo: '',
nombre: '',
descripcion: '',
precio: '',
cantidad: '',
estado: '',
});
const [productos, setProductos] = useState([]);
const addProducto = () => {
setProductos([...productos, producto]);
};
const removeProducto = (e, index) => {
e.preventDefault();
const list = [...productos];
list.splice(index, 1);
setProductos(list);
};
const handleInputChangeProducto = (e, index) => {
e.preventDefault();
const { name, value } = e.target;
const list = [...productos];
list[index][name] = value;
setProductos(list);
};
The return its a table that has a button to add the product
return (
<div>
<table className="table-size" style={{ border: '1px solid black' }}>
<thead>
<tr>
<th scope="col">Nombre</th>
<th scope="col">Descripcion</th>
</tr>
{productos.map((producto, index) => (
<tr key={index}>
<td>
<input
name="nombre"
onChange={(e) => handleInputChangeProducto(e, index)}
/>
</td>
<td>
<input
name="descripcion"
onChange={(e) => handleInputChangeProducto(e, index)}
/>
</td>
<td onClick={(e) => removeProducto(e, index)}>
<Button>Borrar Producto {index}</Button>
</td>
</tr>
))}
</thead>
</table>
<br />
<button onClick={addProducto}>Crear Producto</button>
</div>
I’ve tried separating the "tr" into a separate component but that doesn’t work either.
>Solution :
This is a common issue when using map with index instead of unique key.
So you can try like this:
Please add a global variable key in your case.
let key = 0;
Then set this key in your producto and increase it.
(In my full code, I used codigo as a key field.)
It should always be increased.
On backend API, you should get unique key as well.
Here is a full code.
import React, { useState } from 'react';
import { Button } from 'react-bootstrap';
import './style.css';
let key = 0;
export default function App() {
const [producto, setProducto] = useState({
codigo: '',
nombre: '',
descripcion: '',
precio: '',
cantidad: '',
estado: '',
});
const [productos, setProductos] = useState([]);
const addProducto = () => {
setProductos([...productos, { ...producto, codigo: ++key }]);
};
const removeProducto = (e, index) => {
e.preventDefault();
const list = [...productos];
list.splice(index, 1);
setProductos(list);
};
const handleInputChangeProducto = (e, index) => {
e.preventDefault();
const { name, value } = e.target;
const list = [...productos];
list[index][name] = value;
setProductos(list);
};
console.log({ productos });
return (
<div>
<table className="table-size" style={{ border: '1px solid black' }}>
<thead>
<tr>
<th scope="col">Nombre</th>
<th scope="col">Descripcion</th>
</tr>
{productos.map((producto, index) => (
<tr key={producto.codigo}>
<td>
<input
name="nombre"
onChange={(e) => handleInputChangeProducto(e, index)}
/>
</td>
<td>
<input
name="descripcion"
onChange={(e) => handleInputChangeProducto(e, index)}
/>
</td>
<td onClick={(e) => removeProducto(e, index)}>
<Button>Borrar Producto {index}</Button>
</td>
</tr>
))}
</thead>
</table>
<br />
<button onClick={addProducto}>Crear Producto</button>
</div>
);
}