Hooks en React: useState y useEffect

Los hooks en React son funciones que permiten a los componentes funcionales tener estado y efectos secundarios. En este ejercicio vamos a trabajar con dos de los hooks más utilizados: useState y useEffect.

useState

El hook useState permite a los componentes funcionales tener estado. Para utilizarlo, se debe importar desde la librería de React y llamarlo dentro del componente. useState recibe un argumento que es el valor inicial del estado y devuelve un array con dos elementos: el valor actual del estado y una función para actualizarlo.

Para entender est sección vamos a crear un componente llamado Counter que muestre un contador y un botón para incrementar el contador. El componente debe tener un estado inicial de 0 y la función para actualizar el estado debe incrementar el valor actual en 1.

import { useState } from "react"

const Counter = () => {

    const [number, setNumber] = useState(0)
    const aumentar = () => {
        setNumber(number + 1)
    }

    return (
        <div>
            <h1>{number}</h1>
            <button onClick={aumentar}>Aumentar</button>
        </div>
    )
}

export default Counter

En el código anterior se importa useState desde la librería de React y se llama dentro del componente Counter con un estado inicial de 0. La función aumentar incrementa el valor actual del estado en 1 cada vez que se presiona el botón. Esta es la forma de trabajar con estados en componentes funcionales. Es un poco diferente al uso del DOM en JavaScript puro, pero es muy sencillo y eficiente.

Ahora es necesario importar el componente Counter en el componente principal de la aplicación y renderizarlo.

import Counter from "./components/Counter";

function App() {

  return (
    <>
      <Counter/>
    </>
  )
}

export default App

En el código anterior se importa el componente Counter y se renderiza dentro del componente principal de la aplicación. Al ejecutar la aplicación, se debe mostrar un contador con un botón para incrementar el valor.

Ahora vamos a aumentar 2 funcionalidades al componente Counter. La primera es un botón para disminuir el contador y la segunda es un botón para resetear el contador. Para esto, se deben crear dos funciones que actualicen el estado de forma adecuada.

import { useState } from "react"

const Counter = () => {

    const [number, setNumber] = useState(0)
    const aumentar = () => {
        setNumber(number + 1)
    }

    const disminuir = () => {
        if (number > 0) {
            setNumber(number - 1)
        }
    }

    const reset = () => {
        setNumber(0)
    }

    return (
        <div>
            <h1>{number}</h1>
            <button onClick={aumentar}>Aumentar</button>
            <button onClick={disminuir}>Disminuir</button>
            <button onClick={reset}>Reset</button>
        </div>
    )
}

export default Counter

En el código anterior se crean dos funciones disminuir y reset que disminuyen el contador en 1 y resetean el contador a 0 respectivamente. La función disminuir solo disminuye el contador si el valor actual es mayor que 0. De esta forma, se evita que el contador sea un número negativo.

Para entender mejor useState, vamos a crear un componente llamado Text Que permita mostrar y ocultar un texto. El componente debe tener un estado inicial de true y la función para actualizar el estado debe cambiar el valor actual a false.

import { useState } from "react";

const Text = () => {

    const [text, setText] = useState(true)

    function handleText() {
        setText(!text)
    }

    return (
        <div>
            <h1>{text ? 'Hola' : 'Adios'}</h1>
            <button onClick={handleText}>Cambiar</button>
        </div>
    )
}

export default Text

En el código anterior se crea un componente Text que muestra un texto y un botón para cambiar el texto. El texto inicial es Hola y al presionar el botón, el texto cambia a Adios. Esto se logra con el uso de useState y una función que cambia el valor actual del estado.

Ahora es necesario importar el componente Text en el componente principal de la aplicación y renderizarlo.

import Counter from "./components/Counter";
import Text from "./components/Text";

function App() {

  return (
    <>
      <Counter/>
      <Text/>
    </>
  )
}

export default App

En el código anterior se importa el componente Text y se renderiza dentro del componente principal de la aplicación. Al ejecutar la aplicación, se debe mostrar un texto y un botón para cambiar el texto.

useEffect

El hook useEffect permite a los componentes funcionales tener efectos secundarios. Para utilizarlo, se debe importar desde la librería de React y llamarlo dentro del componente. useEffect recibe dos argumentos: una función que realiza el efecto secundario y un array de dependencias. El efecto secundario se ejecuta cada vez que el componente se renderiza y las dependencias cambian.

Para entender esta sección vamos a crear un componente llamado Fetch que obtenga datos de una API y los muestre en pantalla. El componente debe tener un estado inicial de un array vacío y la función para actualizar el estado debe obtener los datos de la API.

En este caso vamos a utilizar la api https://dog.ceo/dog-api/documentation/random. Esta API nos permite obtener una imagen aleatoria de un perro. Para obtener los datos de la API, se debe utilizar la función fetch de JavaScript y la función json para convertir los datos en un objeto JSON.

import { useState, useEffect } from "react";

const Fetch = () => {

    const [dog, setDog] = useState([])

    useEffect(() => {
        fetch('https://dog.ceo/api/breeds/image/random')
            .then(response => response.json())
            .then(data => setDog(data.message))
    }, [])

    return (
        <div>
            <img
            style={
                {
                    width: '300px',
                    height: '300px',
                    borderRadius: '10px'
                }
            } 
            src={dog} 
            alt="dog"/>
        </div>
    )
}

export default Fetch

En el código anterior se importa useState y useEffect desde la librería de React y se llama dentro del componente Fetch. useEffect se utiliza para obtener los datos de la API y actualizar el estado con los datos obtenidos. La función fetch obtiene los datos de la API y la función json convierte los datos en un objeto JSON. El estado dog se actualiza con la imagen obtenida de la API.

Ahora es necesario importar el componente Fetch en el componente principal de la aplicación y renderizarlo.

import Fetch from "./components/Fetch";

function App() {

  return (
    <>
      <Fetch/>
    </>
  )
}

export default App

En el código anterior se importa el componente Fetch y se renderiza dentro del componente principal de la aplicación. Al ejecutar la aplicación, se debe mostrar una imagen de un perro obtenida de la API.

Para entender mejor useEffect, vamos a crear un componente llamado Clock que muestre la hora actual y se actualice cada segundo. El componente debe tener un estado inicial de la hora actual y la función para actualizar el estado debe obtener la hora actual.

import { useState, useEffect } from "react";

const Clock = () => {

    const [time, setTime] = useState(new Date().toLocaleTimeString())

    useEffect(() => {
        const interval = setInterval(() => {
            setTime(new Date().toLocaleTimeString())
        }, 1000)

        return () => clearInterval(interval)
    }, [])

    return (
        <div>
            <h1>{time}</h1>
        </div>
    )
}

export default Clock

En el código anterior se importa useState y useEffect desde la librería de React y se llama dentro del componente Clock. useEffect se utiliza para obtener la hora actual y actualizar el estado con la hora obtenida. La función setInterval se utiliza para actualizar la hora cada segundo y la función clearInterval se utiliza para detener el intervalo cuando el componente se desmonta.

Ahora es necesario importar el componente Clock en el componente principal de la aplicación y renderizarlo.

import Clock from "./components/Clock";

function App() {

  return (
    <>
      <Clock/>
    </>
  )
}

export default App

En el código anterior se importa el componente Clock y se renderiza dentro del componente principal de la aplicación. Al ejecutar la aplicación, se debe mostrar la hora actual y actualizarse cada segundo.

Reto

  1. Crear un componente llamado Form que tenga un input y un botón. El input debe permitir al usuario ingresar un nombre y el botón debe mostrar un mensaje de bienvenida con el nombre ingresado. El componente debe tener un estado inicial de un string vacío y la función para actualizar el estado debe obtener el valor del input.

  2. Crear un componente llamado List que muestre una lista de elementos. El componente debe tener un estado inicial de un array vacío y la función para actualizar el estado debe agregar un elemento a la lista. El componente debe tener un input y un botón para agregar elementos a la lista.

  3. Crear un componente llamado Fetch2 que obtenga datos de una API y los muestre en pantalla. El componente debe tener un estado inicial de un objeto vacío y la función para actualizar el estado debe obtener los datos de la API. El componente debe tener un input y un botón para obtener los datos de la API. Puede utilizar esta lista de APIs Disponibles. https://github.com/public-apis/public-apis?tab=readme-ov-file

  4. Crear un componente llamado Clock2 que muestre la hora actual y se actualice cada segundo. El componente debe tener un estado inicial de la hora actual y la función para actualizar el estado debe obtener la hora actual. El componente debe tener un botón para detener la actualización de la hora.

Conclusiones

Los hooks en React son funciones que permiten a los componentes funcionales tener estado y efectos secundarios. useState se utiliza para tener estado en componentes funcionales y useEffect se utiliza para tener efectos secundarios en componentes funcionales. Estos hooks son muy útiles para trabajar con componentes funcionales en React y permiten tener un código más limpio y eficiente.

En este ejercicio aprendimos a utilizar los hooks useState y useEffect en React. Creamos varios componentes funcionales que utilizan estos hooks para tener estado y efectos secundarios. También aprendimos a trabajar con APIs y a actualizar la hora actual cada segundo. Los hooks en React son una forma muy eficiente de trabajar con componentes funcionales y permiten tener un código más limpio y fácil de mantener.

Resumen

  • useState permite a los componentes funcionales tener estado.
  • useEffect permite a los componentes funcionales tener efectos secundarios.
  • useState y useEffect son dos de los hooks más utilizados en React.
  • Los hooks en React permiten tener un código más limpio y eficiente.