useState, arrays y objetos
Estado: arrays y objetos
Trabajar con arrays y objetos como estado tiene la peculiaridad en React de que cada vez que queremos hacer alguna modificación a alguno de estos, tenemos que proporcionar un nuevo array u objeto. Para esto, podemos aprovechar varios métodos y técnicas, como todos los métodos que devuelvan un nuevo elemento (map
, filter
, reduce
, slice
) y el spread operator
Spread operator
El spread operator
es una característica de ES6. La sintaxis es la siguiente:
const numeros = [1, 2, 3, 4]console.log(...numeros) //
El spread operator
se escribe con 3 puntos (...
) seguido del nombre del array (u objeto), y contiene todos los elementos (u propiedades) del mismo. En principio esto no parece muy útil, pero nos permite hacer cosas como la siguiente:
const frutas = ['kiwi', 'uva']const frutasYVerduras = ['lechuga', ...frutas, 'repollo']console.log(frutasYVerduras) // ['lechuga', 'kiwi', 'uva', 'repollo']
Lo mismo con un objeto:
const persona = {nombre: 'Ada',apellido: 'Lovelace'}const empleada = {puesto: 'desarrolladora',infoPersonal: {...persona}}console.log(empleada) /** {puesto: 'desarrolladora',infoPersonal: {nombre: 'Ada',apellido: 'Lovelace'}} */
Trabajando con arrays
Vaciando un array
Reemplazamos el array anterior por uno nuevo y vacío
setFruits([])
Concatenando arrays
Creamos un nuevo array que contenga todos los ítems de distintos arrays
setFoods([...salads, ...desserts, ...snacks])
Agregando un item
Creamos un nuevo array que contenga todos los ítems del array original, más el nuevo
setFruits([...fruits, 'Pera'])
Eliminando un item
Filtramos el array original buscando sólo aquellos elementos que no queremos eliminar (es decir, los que son distintos al que queremos sacer) y obtenemos un nuevo array con todos los ítems menos el que no necesitamos (se pueden eliminar más ítems agregando más condiciones)
setFruits(fruits.filter(fruit => fruit !== 'Manzana'))
También podemos utilizar slice si sabemos el índice del elemento que queremos extraer
setFruits(fruits.slice(3, 5))
Reemplazando un item
Obtenemos un nuevo array resultado de mapear todos los elementos del array a sí mismo, excepto el que queremos cambiar, que se mapea a uno nuevo
setFruits(fruits.map(fruit => fruit === 'Manzana' ? 'Pera' : fruit))
Trabajando con objetos
Agregando una propiedad
Creamos un nuevo objeto que contenga todos las propiedades del objeto original, más la nueva
setAnimal({ ...animal, tipo: 'Perro'})
Modificando una propiedad
Creamos un nuevo objeto que contenga todos las propiedades del objeto original, y agregamos la que queremos modificar, que si ya estaba en las anteriores se sobreescribe
setAnimal({ ...animal, tipo: 'Perro'})
Eliminando una propiedad
Desestructuramos el objeto en la propiedad que queremos eliminar y las demás, y creamos un objeto nuevo con las demás
const { propToDelete, ...otherProps } = myObjectsetObject(otherProps)
Uniendo las propiedades de varios objetos
Creamos un nuevo objeto que contenga todos las propiedades de distintos objetos
setUser({...personalInfo, ...contactInfo, ...workInfo})
Trabajando con propiedades anidades
Si bien React no está pensado para utilizar estado anidado, y por lo tanto no es recomendable hacerlo y siempre que se pueda hay que evitarlo, hay veces que no tenemos muchas alternativas. Por lo tanto, si necesitamos actualizar alguna propiedades anidada, podemos utilizar las técnicas anteriores para ir reconstruyendo el objeto:
setUser({...user,personalInfo: {...user.personalInfo,name: 'Ada'}})