Inmutabilidad en Redux con spread operator

Resumen

La inmutabilidad es uno de esos conceptos que parecen simples en teoría, pero que cambian por completo la forma en que tu aplicación responde con Redux. Aquí aprenderás qué significa inmutabilidad en JavaScript, por qué Redux la necesita para rerenderizar tu UI y cómo aplicarla con dos técnicas concretas: object assign y spread operator.

¿Qué es la inmutabilidad y por qué importa en Redux?

Si buscas el término en un diccionario, encontrarás una definición parecida a esta: algo que no puede ser cambiado después de su creación. Es decir, una vez que un valor se crea, no puede ser mutado.

En el contexto de Redux, esto cobra un peso enorme. Redux no le indicará a la UI que debe cambiar si no detecta que su estado inicial y su estado retornado son exactamente diferentes. Si ambos estados se ven iguales, no da la orden de rerenderizar y tu interfaz se queda quieta aunque tú creas que cambió algo.

¿Por qué Redux necesita inmutabilidad? Porque compara referencias entre el estado anterior y el nuevo. Si mutas el objeto original, ambas referencias apuntan al mismo lugar y Redux interpreta que nada cambió.

¿Cómo se ve el problema cuando mutas el estado?

Imagina un objeto userInfo con tres propiedades: nombre, edad y correo. La idea es sumar un año a la edad porque Eddie cumplió años.

La forma mutable se ve así:

javascript function updateAge(userInfo) { userInfo.age = userInfo.age + 1; return userInfo; }

Al correrlo, Eddie pasa de 22 a 23 años. Pero ojo: el objeto original también muestra 23. El estado inicial y el estado final son idénticos porque modificaste el mismo objeto en memoria. Aquí es donde Redux no detecta diferencias y tu UI no se actualiza, por más que te rompas la cabeza buscando el bug.

¿Cómo aplicar inmutabilidad con Object.assign y spread operator?

Hay dos formas claras de respetar la inmutabilidad en JavaScript sin recurrir a librerías externas. Ambas crean un objeto nuevo en lugar de modificar el original.

¿Cómo funciona Object.assign para crear un objeto nuevo?

Object.assign recibe tres argumentos: el target, que es a qué le vas a aplicar el cambio, y las fuentes que se van a fusionar dentro de ese target.

javascript function updateAge(userInfo) { return Object.assign({}, userInfo, { age: userInfo.age + 1 }); }

El primer parámetro es un objeto vacío, lo que crea una nueva referencia en memoria. El segundo copia todo lo que hay en userInfo. El tercero sobrescribe la propiedad age. Al ejecutarlo, el objeto inicial se mantiene intacto y solo el objeto retornado refleja el cambio.

¿Por qué el spread operator es más legible?

Desde cierta versión de JavaScript tienes a disposición el spread operator, que hace lo mismo pero con una sintaxis más limpia.

javascript function updateAge(userInfo) { return { ...userInfo, age: userInfo.age + 1, }; }

Los tres puntos despliegan todas las propiedades del objeto original dentro de uno nuevo, y luego sobrescribes únicamente lo que necesitas. El resultado es el mismo que con Object.assign: objeto inicial intacto, nuevo objeto con la propiedad modificada.

¿Cuál es la diferencia entre Object.assign y spread operator? Ambos crean un objeto nuevo respetando la inmutabilidad. El spread es más corto y legible; Object.assign es más explícito y útil cuando necesitas fusionar varias fuentes dinámicamente.

¿Qué desventajas tiene manejar inmutabilidad solo con JavaScript?

No todo es color de rosa cuando trabajas la inmutabilidad de forma manual. Hay tres puntos que vale la pena tener en mente:

  • Problemas de performance: si no entiendes cómo funciona el garbage collector de JavaScript o no liberas los objetos que vas creando constantemente, generas una acumulación que afecta el rendimiento.
  • Errores humanos: es fácil modificar sin querer el objeto original en lugar de crear uno nuevo, y ese descuido puede pasar desapercibido durante horas de depuración.
  • Menos trazabilidad: cuando algo falla, rastrear en qué punto se mutó el estado o se creó una nueva referencia se vuelve complicado.

¿Existe una librería que resuelva esto? Sí, Immutable JS. Maneja la inmutabilidad por sí sola y solo tienes que aprender su sintaxis y cómo trabajar con sus estructuras.

La próxima vez que tu UI no responda a un cambio en Redux, revisa si estás mutando el estado sin darte cuenta. ¿Ya te pasó? Cuéntame en los comentarios cómo lo resolviste.