Vinculación de inputs a un array en React
Supongamos que en el estado notes se almacena un array:
jsxfunction App() {
const [notes, setNotes] = useState([1, 2, 3]);
return <div>
</div>;
}
Tengamos también una función auxiliar, que calcula la suma de los elementos del array:
jsxfunction getSum(arr) {
let sum = 0;
for (const elem of arr) {
sum += +elem;
}
return sum;
}
function App() {
...
}
Calculemos y mostremos la suma de los elementos de nuestro array del estado, utilizando para esto nuestra función auxiliar:
jsxfunction App() {
const [notes, setNotes] = useState([1, 2, 3]);
return <div>
{getSum(notes)}
</div>;
}
Ahora creemos tres inputs y en value
de cada input escribamos uno de los elementos del array:
jsxfunction App() {
const [notes, setNotes] = useState([1, 2, 3]);
return <div>
<input value={notes[0]} />
<input value={notes[1]} />
<input value={notes[2]} />
{getSum(notes)}
</div>;
}
Ahora agreguemos el evento onChange
a nuestros inputs. Al mismo tiempo, crearemos una única
función manejadora común para este evento:
jsxfunction App() {
const [notes, setNotes] = useState([1, 2, 3]);
function changeHandler(index, event) {
// función manejadora común
}
return <div>
<input value={notes[0]} onChange={event => changeHandler(0, event)} />
<input value={notes[1]} onChange={event => changeHandler(1, event)} />
<input value={notes[2]} onChange={event => changeHandler(2, event)} />
{getSum(notes)}
</div>;
}
Como puedes ver, la función changeHandler
acepta como primer parámetro el número del elemento
del array que edita este input.
Por este número podemos reemplazar el elemento del array por el contenido del input.
Hagámoslo:
jsxfunction changeHandler(index, event) {
setNotes([...notes.slice(0, index), event.target.value, ...notes.slice(index + 1)]);
}
Ahora será posible editar cualquier input, al mismo tiempo reactivamente cambiará el array y, en consecuencia, se recalculará la suma de sus elementos.
Recopilemos todo nuestro código:
jsxfunction App() {
const [notes, setNotes] = useState([1, 2, 3]);
function changeHandler(index, event) {
setNotes([...notes.slice(0, index), event.target.value, ...notes.slice(index + 1)]);
}
return <div>
<input value={notes[0]} onChange={event => changeHandler(0, event)} />
<input value={notes[1]} onChange={event => changeHandler(1, event)} />
<input value={notes[2]} onChange={event => changeHandler(2, event)} />
{getSum(notes)}
</div>;
}
Se puede hacer que los inputs se generen en un bucle:
jsxfunction App() {
const [notes, setNotes] = useState([1, 2, 3]);
function changeHandler(index, event) {
setNotes([...notes.slice(0, index), event.target.value, ...notes.slice(index + 1)]);
}
const result = notes.map((note, index) => {
return <input
key={index}
value={note}
onChange={event => changeHandler(index, event)}
/>;
});
return <div>
{result}
{getSum(notes)}
</div>;
}
Dado el siguiente array:
jsx[1, 2, 3, 4, 5, 6, 7, 8, 9]
Muestra en la pantalla el promedio de los elementos de este array. En un bucle crea inputs para editar los elementos.