44. useState - Creando estados de tipo objetos

 

Tutorial: useState - Creando estados de tipo objetos

Introducción

Hemos visto cómo usar useState con tipos básicos como booleanos, numéricos y strings, pero también podemos tener estados de tipo objeto. Imagina que necesitas que varias propiedades (como el estado de un coche y su kilometraje) estén dentro de un mismo objeto. ¡Vamos a ver cómo hacerlo!

Configuración inicial

Primero, vamos a comentar el código anterior para empezar desde cero. Teníamos un botón para incrementar kilómetros y otro para encender/apagar el coche.

Creando nuestro estado de tipo objeto

jsx

// Importamos useState

import { useState } from 'react';


function App() {

  // Declaramos nuestro estado de tipo objeto

  const [carState, setCarState] = useState({

    started: false,    // El coche empieza apagado

    kilometers: 0      // El kilometraje empieza en 0

  });


  return (

    <div>

      {/* Mostramos el estado del coche */}

      <p>El coche está {carState.started ? 'encendido' : 'apagado'}</p>

      

      {/* Mostramos los kilómetros */}

      <p>Kilómetros: {carState.kilometers} km</p>

    </div>

  );

}

Accediendo a las propiedades del objeto

Como nuestro estado es un objeto, accedemos a sus propiedades usando la notación de punto:

jsx

// Antes (con estado simple):

// {started ? 'encendido' : 'apagado'}


// Ahora (con estado objeto):

// {carState.started ? 'encendido' : 'apagado'}

Actualizando el estado del coche (encender/apagar)

jsx

const toggleCar = () => {

  setCarState({

    ...carState,           // Copiamos todas las propiedades actuales

    started: !carState.started  // Actualizamos solo 'started'

  });

};


// En el JSX:

<button onClick={toggleCar}>

  {carState.started ? 'Apagar coche' : 'Encender coche'}

</button>

¡IMPORTANTE! El spread operator (...)

El spread operator (...) es crucial porque:

  • Copia todas las propiedades actuales del estado

  • Evita que se pierdan propiedades al actualizar

  • Sin él, el objeto se sobrescribiría completamente


Incrementando los kilómetros

jsx

const increaseKilometers = (km) => {

  // Verificamos que el coche esté encendido

  if (!carState.started) {

    alert('El coche está apagado');

    return;

  }

  

  setCarState({

    ...carState,  // Copiamos todas las propiedades

    kilometers: carState.kilometers + km  // Actualizamos kilómetros

  });

};


// En el JSX:

<button onClick={() => increaseKilometers(5)}>

  Aumentar 5 km

</button>







Código completo

import { useState } from 'react';


function App() {

  const [carState, setCarState] = useState({

    started: false,

    kilometers: 0

  });


  const toggleCar = () => {

    setCarState({

      ...carState,

      started: !carState.started

    });

  };


  const increaseKilometers = (km) => {

    if (!carState.started) {

      alert('El coche está apagado');

      return;

    }

    

    setCarState({

      ...carState,

      kilometers: carState.kilometers + km

    });

  };


  return (

    <div>

      <h1>Control del Coche</h1>

      

      <p>El coche está {carState.started ? 'encendido' : 'apagado'}</p>

      <p>Kilómetros: {carState.kilometers} km</p>

      

      <button onClick={toggleCar}>

        {carState.started ? 'Apagar coche' : 'Encender coche'}

      </button>

      

      <button onClick={() => increaseKilometers(5)}>

        Aumentar 5 km

      </button>

    </div>

  );

}export default App;

¿Qué pasa si NO usamos el spread operator?

Si actualizamos el estado sin el spread operator:

jsx

// ❌ INCORRECTO - Esto borrará todas las otras propiedades

setCarState({

  started: !carState.started

});


// El objeto resultante sería: {started: true}

// ¡Se pierde la propiedad 'kilometers'!

Beneficios de usar objetos en el estado

  1. Organización: Agrupa datos relacionados

  2. Menos estados: En lugar de múltiples useState, tienes uno estructurado

  3. Actualizaciones coordinadas: Puedes actualizar varias propiedades a la vez

Consejos prácticos

  • Siempre usa el spread operator cuando actualices estados de tipo objeto

  • Considera separar estados muy diferentes en distintos useState

  • Para objetos complejos, considera usar useReducer

Conclusión

Los estados de tipo objeto son muy útiles para agrupar información relacionada. Recuerda siempre copiar el estado actual con el spread operator antes de modificarlo para evitar perder datos.

¡Espero que este tutorial te haya sido útil! Si tienes dudas, puedes contactarme a través de mis redes sociales o página web. ¡Nos vemos en el próximo tutorial!




Tutorial 44: useState - Creando estados de tipo objetos

https://44.%2520useState%2520-%2520Creando%2520estados%2520de%2520tipo%2520objetos.png

Introducción

Hemos visto cómo usar useState con tipos básicos como booleanos, numéricos y strings. Pero también podemos tener estados de tipo objeto. Imagina que necesitas que varias propiedades relacionadas (como el estado de un coche y su kilometraje) estén agrupadas dentro de un mismo objeto.

Paso 1: Declarando nuestro estado de tipo objeto

En lugar de tener múltiples useState separados:

javascript

// const [started, setStarted] = useState(false);

// const [countKm, setCountKm] = useState(0);

Creamos un único estado de tipo objeto:

javascript

const [carState, setCarState] = useState({

  started: false,

  countKm: 0

});

Explicación:

  • carState: Objeto que contiene todas las propiedades relacionadas con el coche

  • setCarState: Función para actualizar el estado del coche

  • Inicializamos con: started: false (coche apagado) y countKm: 0 (0 kilómetros)


Paso 2: Mostrando el estado del coche

https://44.%2520useState%2520-%2520Creando%2520estados%2520de%2520tipo%2520objetos%2520(1).png

Ahora que nuestro estado es un objeto, accedemos a sus propiedades usando la notación de punto:

javascript

const checkStateCar = () => {

  if (carState.started) {

    return <span style={{ color: "green" }}>Encendido</span>;

  }

  return <span style={{ color: "red" }}>Apagado</span>;

};


// En el JSX:

<h2>Nuestro coche está: {checkStateCar()}</h2>

<h2>Kilómetros recorridos: {carState.countKm} km</h2>

Paso 3: Actualizando el estado (encender/apagar)

https://44.%2520useState%2520-%2520Creando%2520estados%2520de%2520tipo%2520objetos%2520(2).png

Para actualizar el estado, usamos el spread operator (...) que es CRUCIAL:

javascript

<button

  onClick={() => {

    setCarState({

      ...carState,  // ← ¡IMPORTANTE! Copia todas las propiedades

      started: !carState.started  // Solo cambia esta propiedad

    });

  }}

>

  Encender / Apagar

</button>


¿Por qué el spread operator?

  • Copia todas las propiedades existentes de carState

  • Evita que se pierdan propiedades al actualizar

  • Sin él: {started: true} eliminaría countKm del objeto

Paso 4: Incrementando los kilómetros

https://44.%2520useState%2520-%2520Creando%2520estados%2520de%2520tipo%2520objetos%2520(3).png

javascript

const increaseKm = (num) => {

  if (carState.started) {

    setCarState({

      ...carState,  // Copiamos el estado actual

      countKm: carState.countKm + num  // Solo actualizamos countKm

    });

  } else {

    alert("El coche está apagado.");

  }

};







Paso 5: Código completo

export default function Car() {

  const [carState, setCarState] = useState({

    started: false,

    countKm: 0

  });


  const checkStateCar = () => {

    if (carState.started) {

      return <span style={{ color: "green" }}>Encendido</span>;

    }

    return <span style={{ color: "red" }}>Apagado</span>;

  };


  const increaseKm = (num) => {

    if (carState.started) {

      setCarState({

        ...carState,

        countKm: carState.countKm + num

      });

    } else {

      alert("El coche está apagado.");

    }

  };


  return (

    <div>

      <h2>Nuestro coche está: {checkStateCar()}</h2>

      <h2>Kilómetros recorridos: {carState.countKm} km</h2>

      

      <button

        onClick={() => {

          setCarState({

            ...carState,

            started: !carState.started

          });

        }}

      >

        Encender / Apagar

      </button>

      

      <button

        onClick={() => {

          increaseKm(5);

        }}

      >

        Incrementar kilómetros

      </button>

    </div>

  );

}

¿Qué pasa si NO usamos el spread operator?

ERROR COMÚN:

javascript

// ❌ INCORRECTO

setCarState({

  started: !carState.started

});

Resultado:

  • Estado anterior: {started: false, countKm: 50}

  • Estado nuevo: {started: true} ← ¡Se pierde countKm!

CORRECTO:

javascript

// ✅ CORRECTO

setCarState({

  ...carState,  // Mantiene countKm: 50

  started: !carState.started  // Cambia solo started

});

Ventajas de usar estados tipo objeto

  1. Organización: Datos relacionados se agrupan juntos

  2. Menos estados: En lugar de múltiples useState, uno estructurado

  3. Actualizaciones coordinadas: Puedes actualizar varias propiedades a la vez

  4. Mejor legibilidad: Fácil de entender la relación entre datos

Consejos prácticos

  • Siempre usa el spread operator al actualizar objetos

  • Considera separar en distintos useState si los datos no están relacionados

  • Para objetos complejos o lógica de actualización complicada, considera usar useReducer

Conclusión

Los estados de tipo objeto son una herramienta poderosa en React que te permite organizar mejor tu código cuando tienes datos relacionados. La clave está en recordar siempre usar el spread operator para preservar las propiedades que no quieres modificar.

¡Espero que este tutorial te haya sido útil! Si tienes dudas, puedes contactarme a través de mis redes sociales o página web.


Comentarios

Entradas más populares de este blog

18-Ciclo de Vida de un Componente React

20. ¿Que son los Props de React?

17-Componentes en React-estado