Regístrate para acceder a más de 15 cursos gratuitos de programación con un simulador

Inmutabilidad JS: React

La inmutabilidad del estado es uno de los temas clave en React. Es fácil de seguir cuando trabajamos con tipos de datos primitivos, pero puede resultar complicado para un usuario no preparado cuando se trata de tipos de datos compuestos como objetos y arrays. En esta lección vamos a explorar las formas básicas de actualizar parcialmente objetos y arrays.

Además de los ejemplos en JS puro, vamos a mostrar ejemplos utilizando la biblioteca immutability-helper, que se creó para facilitar este tipo de operaciones. Es especialmente útil cuando el código en JS se vuelve demasiado complejo.

Arrays

Array: agregar

Lo más sencillo es agregar elementos a un array:

const items = ['uno', 'dos', 'tres'];
const item = 'cuatro';
const newItems = [...items, item];
// ['uno', 'dos', 'tres', 'cuatro'];

Si deseas agregar un elemento al principio, solo necesitas intercambiar los elementos del array:

const newItems = [item, ...items];
// ['cuatro', 'uno', 'dos', 'tres'];

Uso de immutability-helper

import update from 'immutability-helper';

const state1 = ['x'];
const state2 = update(state1, { $push: ['y'] }); // ['x', 'y']

Array: eliminar

Un ejemplo más interesante. Para eliminar con éxito, necesitamos saber qué queremos eliminar. Esto significa que cada elemento en la lista debe tener un identificador. Para eliminar, utilizamos el buen y viejo filtrado.

const newItems = items.filter((item) => item.id !== id);

Puede surgir la pregunta: ¿de dónde viene el identificador dentro del controlador? Aquí es donde entran en juego los cierres.

Ver el Pen js_react_immutability_array_remove_element de Códica (@hexlet) en CodePen.

Observa la forma en que se define el controlador: removeItem = (id) => (e) => { y cómo se utiliza onClick={this.removeItem(id)}.

Uso de immutability-helper

const index = 5;
const newItems = update(items, {$splice: [[index, 1]]});

Eliminar mediante filtrado en JS puro es la forma más óptima. Con immutability-helper, se vuelve más complicado.

Array: modificar

Desafortunadamente, sin herramientas adicionales, el código de la solución se vuelve demasiado engorroso. Se proporciona como referencia, pero no recomendamos utilizarlo en código real.

const index = items.findIndex((item) => item.id === id);
const newItem = { ...items[index], value: 'otro valor' };
const newItems = [...items.slice(0, index), newItem, ...items.slice(index + 1)];

Uso de immutability-helper

const collection = { children: ['cero', 'uno', 'dos'] };
const index = 1;
const newCollection = update(collection, { children: { [index]: { $set: 1 } } });
// { children: ['cero', 1, 'dos'] }

Como puedes ver, este método es mucho más sencillo y limpio, así que recomendamos su uso.

Objetos

Objeto: agregar

Tan sencillo como con un array.

const items = { a: 1, b: 2 };
const newItems = { ...items, c: 3 };
// { a: 1, b: 2, c: 3 }

O, si la clave se calcula dinámicamente, debes hacer lo siguiente:

const items = { a: 1, b: 2 };
const key = 'c';
const newItems = { ...items, [key]: 3 };
// { a: 1, b: 2, c: 3 }

Objeto: eliminar

La desestructuración es útil en este caso:

const { deletedKey, ...newState } = state;

Uso de immutability-helper

import update from 'immutability-helper';

const state = { a: 1, c: 3 };
const updatedState = update(state, {
  $unset: ['c'],
});
// { a: 1 }

Objeto: modificar

Es exactamente igual que agregar.

const items = { a: 1, b: 2 };
const newItems = { ...items, a: 3 };
// { a: 3, b: 2 }

Uso de immutability-helper

const data = { a: 1, b: 2 };
const key = 'a';
const newData = update(data, { [key]: { $set: 3 } });
// { a: 3, b: 2 }

Anidamiento profundo

En los ejemplos anteriores, en su mayoría se pueden utilizar las funciones estándar de JS, y solo en algunas situaciones es más conveniente utilizar soluciones de terceros. En el código real, esto será igual, especialmente si se tiene en cuenta la recomendación de React de mantener el estado lo más plano posible. Sin embargo, en algunas situaciones, los datos que queremos modificar no están en la superficie, sino en lo profundo de las estructuras. Desafortunadamente, en estas situaciones, el código JS normal se vuelve engorroso. Y aquí es cuando definitivamente necesitamos una biblioteca adicional.

import update from 'immutability-helper';

const myData = {
  x: { y: { z: 5 } },
  a: { b: [1, 2] },
};

const newData = update(myData, {
  x: { y: { z: { $set: 7 } } },
  a: { b: { $push: [9] } }
});
console.log(newData)
// => { x: { y: { z: 7 } }, a: { b: [ 1, 2, 9 ] } }

Alternativas

immutability-helper no es la única biblioteca para este tipo de tareas. Aquí hay algunas otras populares:

  • immutable-js es una biblioteca basada en datos persistentes.
  • updeep es una biblioteca que utiliza ampliamente el currying.
  • immerjs es probablemente la biblioteca más popular en JS para trabajar con datos inmutables.

Materiales adicionales

  1. Actualizar arrays en el estado / React
  2. Actualizar objetos en el estado / React

Para acceder completo a curso necesitas un plan básico

El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.

Obtener acceso
130
cursos
1000
ejercicios
2000+
horas de teoría
3200
test

Obtén acceso

Cursos de programación para principiantes y desarrolladores experimentados. Comienza tu aprendizaje de forma gratuita

  • 130 cursos, 2000+ horas de teoría
  • 1000 ejercicios prácticos en el navegador
  • 360 000 estudiantes
Al enviar el formulario, aceptas el «Política de privacidad» y los términos de la «Oferta», y también aceptas los «Términos y condiciones de uso»

Nuestros graduados trabajan en empresas como:

Bookmate
Health Samurai
Dualboot
ABBYY