Cómo crear una aplicación con React usando Hooks

JavascriptReact

En este tutorial vamos a ver cómo puedes crear una aplicación CRUD con React usando Hooks, que son una alternativa a los componentes de clase de React, agregando nuevas funcionalidades a los componentes funcionales.

Muchas de las funcionalidades de los componentes de clase, como el estado los métodos, no estaban antes disponibles en los componentes funcionales. Sin embargo, esto cambia con el uso de Hooks.

Antes de comenzar, vamos a ver un ejemplo de un sencillo componente funcional de React:

const Ejemplo = () => {
  return <div>Componente funcional</div>
}

A continuación tienes un ejemplo de un componente de clase:

class Ejemplo extends Component {
  render() {
    return <div>Soy un componente de clase</div>
  }
}

Lo que haremos en este tutorial será crear una pequeña aplicación sin  componentes de clase, ya que usaremos únicamente componentes funcionales con Hooks. La aplicación permitirá realizar las funcionalidades CRUD típicas, que consisten en crear datos, leerlos, actualizarlos y eliminarlos.

A continuación puedes ver tanto el código del proyecto como la aplicación que vamos a crear:

Introducción

Antes de comenzar, es recomendable que tengas ciertos conocimientos previos tanto de JavaScript como de React. Por ello, es recomendable que o bien hayas usado React previamente o que hayas seguido el siguiente tutorial, en el que explico cómo usar React desde cero:

En este tutorial usaremos el framework CSS Bootstrap, ya que no es el objetivo de este tutorial el de aprender CSS. Además, en caso de que no tengas conocimientos de JavaScript, de HTML o de CSS, consulta los siguientes tutoriales:

No es necesario que sepas usar Bootstrap, ya que únicamente usaremos algunas clases básicas, pero en caso de que no conozcas este framework y quieras aprenderlo, puedes consultar este tutorial:

Además, también usaremos la línea de comandos. Usaremos solamente los comandos necesarios para usar React. En caso de que no sepas usar la línea de comandos y quieras aprender a usarla, consulta el tutorial de introducción a la línea de comandos.

La aplicación que crearemos nos permitirá agregar, leer, actualizar y eliminar los datos de una serie de usuarios. Para ello usaremos tanto Hooks de estado como Hooks de efecto en componentes funcionales, que nos permitirán dotar a los componentes funcionales de funcionalidades que antes estaban restringidas a las clases.

Creación del proyecto

Para crear el proyecto usaremos la utilidad create-react-app, que podrás ejecutar mediante el gestor de paquetes npm, que se instala con Node.js. En caso de que no tengas Node.js instalado en tu sistema, consulta cómo instalar Node.js. Además, también puedes consultar el tutorial de introducción a Node.js y npm.

Para crear el proyecto, abre una ventana de línea de comandos, sitúate en el directorio en el que quieres crear el proyecto y ejecuta este comando:

npx create-react-app tutorial-react-hooks

Cuando finalice la creación del proyecto, accede al directorio recién creado y ejecuta el siguiente comando para instalar los paquetes necesarios.

npm i

Una vez haya finalizado la instalación de los paquetes, usa el siguiente comando para iniciar el servidor de desarrollo:

npm start

Configuración inicial del proyecto

Una vez en el directorio del proyecto, elimina todos los archivos del directorio /src a excepción de los archivos App.js, index.js e index.css.

Edita el archivo index.css y copia y pega en su interior el código de del framework Bootstrap, que podrás encontrar aquí. De este modo nos despreocuparemos del diseño de las clases CSS.

Luego edita el archivo index.js y elimina la referencias a los service workers, de modo que el archivo quede así:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

Seguidamente edita el archivo App.js, en el que, en lugar de una clase, sencillamente agregaremos un componente funcional para la aplicación llamado App:

import React from 'react';

const App = () => {
  return (
    <div className="container mt-4">
      <h1>Tutorial React Hooks</h1>
      <div className="row">
        <div className="col-md-4 mt-4">
          <h2>Agregar usuario</h2>
        </div>
        <div className="col-md-8 mt-4">
          <h2>Ver usuarios</h2>
        </div>
      </div>
    </div>
  )
}

export default App;

Si ahora abres tu navegador para ver el resultado deberías ver algo así:

Usando Hooks de estado

Antes de continuar vamos a ver un ejemplo de un componente de clase típico y cómo podríamos refactorizarlo para crear un componente funcional que disponga de estado gracias al uso de Hooks. Los ejemplos de este apartado no forman parte del proyecto; se exponen únicamente con el fin de entender las diferentes entre el estado de un componente de clase y un componente funcional que use Hooks de estado.

En un componente de clase dispones de un único objeto de estado que puedes actualizar mediante el método setState(). Vamos a ver un ejemplo de un componente de clase en el que representamos una empresa de alquiler de coches, en el que además usamos un estado:

class App extends Component {
  estadoInicial = {
    marca: '',
    modelo: '',
    disponible: false,
  }

  state = estadoInicial;

  actualizarCoche = (coche) => {
    this.setState({ marca: coche.marca, modelo: coche.modelo, disponible: coche.disponible });
  }
}

Cuando usas Hooks de estado, existe un función que permite establecer el estado y otra que permite obtenerlo, pudiendo existir tantos objetos de estado como desees:

const App = () => {
  const estadoCocheInicial = {
    marca: '',
    modelo: '',
    disponible: false,
  }

  const [coche, setCoche] = useState(estadoCocheInicial);

  const actualizarCoche = (coche) => {
    setCoche({ marca: coche.marca, modelo: coche.modelo, disponible: coche.disponible });
  }
}

Es decir, asociamos el estado coche al la función setCoche, que usaremos para establecer el estado. Siguiendo esta misma filosofía, podríamos establecer más objetos de estado.

Desarrollo de la aplicación

Vamos a comenzar a programar la aplicación. Primero crearemos los componentes necesarios y su parte visual con datos de prueba, y luego agregaremos las funcionalidades que nos permitirán realizar las acciones CRUD.

Creación de las vistas

Primero vamos a mostrar los datos de todos los usuarios en un tabla. Para ello vamos a crear un directorio llamado /tablas en el interior del directorio /src. En su interior crearemos el archivo TablaUsuarios.js con este código:

import React from 'react';

const TablaUsuarios = () => (
  <table className="table mt-4">
    <thead className="thead-dark">
      <tr>
        <th>Nombre</th>
        <th>Usuario</th>
        <th>Acciones</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Dukecito</td>
        <td>Nukemito</td>
        <td>
          <button type="button" className="btn btn-primary btn-sm m-1">Editar</button>
          <button type="button" className="btn btn-primary btn-sm m-1">Eliminar</button>
        </td>
      </tr>
    </tbody>
  </table>
)

export default TablaUsuarios;

Este sería el resultado con lo que hemos hecho hasta ahora:

Ahora vamos a agregar datos con usuarios de ejemplo y a establecerlos como los datos por defecto mediante la función useState de React. Para ello, edita el archivo que contiene el componente App y agrega este código:

import React, { useState } from 'react';
import TablaUsuarios from './tables/TablaUsuarios';

const App = () => {

  const datosUsuario = [
    { id: 1, nombre: 'Edu', apellido: 'Lázaro' },
    { id: 2, nombre: 'Ana', apellido: 'Rodríguez' },
    { id: 3, nombre: 'Marcos', apellido: 'González' },
  ];

  const [usuarios, setUsuarios] = useState(datosUsuario);

  return (
    <div className="container">
      <h1>Tutorial React Hooks</h1>
      <div className="row">
        <div className="col-md-4">
          <h2>Agregar usuario</h2>
        </div>
        <div className="col-md-4">
          <h2>Ver usuarios</h2>
          <TablaUsuarios usuarios={usuarios} />
        </div>
      </div>
    </div>
  );
}

export default App;

Tal y como ves, primero hemos importado el componente TablaUsuarios. Luego hemos pasado la lista de usuarios al componente TablaUsuarios, por lo que deberemos editar este componente para que acepte la lista de usuarios como propiedad, de modo que pueda mostrarlos o mostrar un mensaje de aviso en caso de que no existan usuarios. Los botones de edición y eliminación no harán nada todavía:

import React from 'react';

const TablaUsuarios = (props) => (
  <table className="table mt-4">
    <thead className="thead-dark">
      <tr>
        <th>Nombre</th>
        <th>Usuario</th>
        <th>Acciones</th>
      </tr>
    </thead>
    <tbody>
      {props.usuarios.length > 0 ? (
        props.usuarios.map((usuario) => (
          <tr key={usuario.id}>
            <td>{usuario.nombre}</td>
            <td>{usuario.apellido}</td>
          <td>
            <button type="button" className="btn btn-primary btn-sm m-1">Editar</button>
            <button type="button" className="btn btn-primary btn-sm m-1">Eliminar</button>
          </td>
        </tr>
      ))
    ) : (
      <tr>
        <td colSpan={3}>No se han agregado usuarios</td>
      </tr>
    )}
    </tbody>
  </table>
)

export default TablaUsuarios;

Hemos usado el método map para recorrer los usuarios que hemos pasado al componente como propiedad, asignando un índice a cada usuario mediante el atributo key. Este sería el resultado con lo que hemos hecho hasta ahora:

Y con esto hemos terminado la plantilla básica de la aplicación. A continuación dotaremos de funcionalidad a nuestra aplicación.

Creación de usuarios

Vamos a crear un formulario que nos permita agregar un nuevo usuario a la aplicación. Lo primero que haremos será crear la función que nos permita agregar el nuevo usuario al estado que hemos definido. Para ello podemos usar la función setUsuarios que hemos creado.

Podríamos usar una API, pero sale del alcance de este tutorial, que únicamente pretende explicar cómo funcionan las Hooks en React. Mediante una API obtendríamos un id para cada elementos y se incrementaría automáticamente, pero cuando trabajamos con datos locales tenemos que generarlo nosotros de algún modo para simular dicho comportamiento.

Vamos a crear la función agregarUsuario, que aceptará un objeto usuario como parámetro y lo agregará al array de usuarios de nuestro estado. Para combinar el array de usuarios existente con el nuevo usuario, usaremos el operador spread de propagación ...usuarios, de modo que se conserven los usuarios que ya existían en el array. Agrega la siguiente función al archivo App.js, encima de la sentencia return del componente App:

const agregarUsuario = (usuario) => {
  usuario.id = usuarios.length + 1;
  setUsuarios([...usuarios, usuario]);
}

Necesitamos crear un formulario que nos permita introducir los datos del nuevo usuario, y para ello usaremos un nuevo componente. El componente se llamará FormularioAgregarUsuario, residirá en el directorio /forms, que tendremos que crear, y por ahora solamente haremos referencia al mismo en la cabecera el archivo App.js. Vamos a agregar este nuevo componente a la izquierda de la tabla, y le pasaremos la función agregarUsuario como propiedad:

import React, { useState } from 'react';
import TablaUsuarios from './tables/TablaUsuarios';
import FormularioAgregarUsuario from './forms/FormularioAgregarUsuario';

const App = () => {

  const datosUsuario = [
    { id: 1, nombre: 'Edu', apellido: 'Lázaro' },
    { id: 2, nombre: 'Ana', apellido: 'Rodríguez' },
    { id: 3, nombre: 'Marcos', apellido: 'González' },
  ];

  const [usuarios, setUsuarios] = useState(datosUsuario);

  const agregarUsuario = (usuario) => {
    usuario.id = usuarios.length + 1;
    setUsuarios([...usuarios, usuario]);
  }

  return (
    <div className="container">
      <h1>Tutorial React Hooks</h1>
      <div className="row">
        <div className="col-md-4">
          <h2>Agregar usuario</h2>
          <FormularioAgregarUsuario agregarUsuario={agregarUsuario} />
        </div>
        <div className="col-md-4">
          <h2>Ver usuarios</h2>
          <TablaUsuarios usuarios={usuarios} />
        </div>
      </div>
    </div>
  );
}

export default App;

Es importante que, tal y como hemos hecho, no pases la función agregarUsuario con paréntesis, ya que de lo contrario la función se ejecutaría, pasando en realidad su resultado.

A continuación vamos a crear el componente FormularioAgregarUsuario, que incluye el formulario que nos permitirá agregar usuarios. Para ello crearemos el directorio /forms en el directorio /src y en su interior crearemos el archivo FormularioAgregarUsuario.js:

import React, { useState } from 'react';

const FormularioAgregarUsuario = (props) => {
  return (
    <form>
      <div className="form-group">
        <label>Nombre</label>
        <input id="nombre" className="form-control" type="text" name="nombre" value="" />
      </div>
      <div className="form-group">
        <label>Apellido</label>
        <input id="apellido" className="form-control" type="text" name="apellido" value="" />
      </div>
      <div className="form-group">
        <button type="submit" className="btn btn-primary">Agregar usuario</button>
      </div>
    </form>
  )
}

export default FormularioAgregarUsuario;

Por ahora todavía no puedes agregar usuarios usando el formulario, por lo que el botón de submit no funcionará. Comenzaremos creando otro estado en el componente para almacenar los usuarios que el usuario escriba en el formulario. Inicialmente crearemos un estado por defecto con valores vacíos, que resulta útil en caso de que queramos devolver los valores del formulario a su valor inicial:

const estadoInicialFormulario = { id: null, nombre: '', apellido: '' };
const [usuario, setUsuario] = useState(estadoInicialFormulario);

Seguidamente crearemos una función que nos permita actualizar el estado del formulario. La idea es que el estado del formulario cambie cuando se modifique alguno de los campos. La función aceptará el evento event, que es pasado siempre a través de cualquier evento on del DOM:

const gestionarCampo = (event) => {
  const { name, value } = event.target;
  setUsuario({ ...usuario, [name]: value });
}

Tal y como ves, mediante destructuring de objetos obtenemos nombre del campo del formulario, establecido mediante el atributo name. También obtenemos el valor del campo, establecido mediante el atributo value. Luego hemos usado el método setUsuario para asignar los valores obtenidos de los campos nombre y apellido al estado usuario del formulario.

Ahora ya solo nos falta usar los datos del estado usuario en el atributo value de los campos nombre y apellido. Del mismo modo, asignamos la función gestionarCampo al evento onChange de ambos campos:

<form>
  <div className="form-group">
    <label>Nombre</label>
      <input
        id="nombre"
        className="form-control"
        type="text"
        name="nombre"
        value={usuario.nombre}
        onChange={gestionarCampo}
    />
  </div>
  <div className="form-group">
    <label>Apellido</label>
    <input
      id="apellido"
      className="form-control"
      type="text"
      name="apellido"
      value={usuario.apellido}
      onChange={gestionarCampo}
    />
  </div>
  <div className="form-group">
    <button type="submit" className="btn btn-primary">Agregar usuario</button>
  </div>
</form>

Por último, tendremos que hacer posible que el formulario envíe los datos de vuelta al componente App. Para ello usaremos la función agregarUsuario, que hemos pasado como propiedad al componente FormularioAgregarUsuario desde el componente App.

Vamos a agregar una función onSubmit al formulario, que gestionará el envío del formulario, enviando los datos del usuario de vuelta al componente App mediante el método agregarUsuario:

<form
  onSubmit={event => {
    event.preventDefault();
    if (!usuario.nombre || !usuario.apellido) return;

    props.agregarUsuario(usuario);
    setUsuario(estadoInicialFormulario);
  }}
>

Lo primero que hemos hecho en el interior de la acción onSubmit de la etiqueta form ha sido evitar que el formulario se envíe mediante el método event.preventDefault. No debes confundir este método con el método event.stopPropagation. Si no sabes en qué se diferencian, consulta cuáles son las diferencias entre event.preventDefault y event.stopPropagation.

También comprobamos de un modo muy básico que los campos nombre y apellido no estén vacíos. Luego llamamos a la función agregarUsuario y finalmente usamos la función setUsuario para establecer el valor por defecto de los campos, de modo que contengan una cadena vacía. A continuación puedes ver el código completo del componente FormularioAgregarUsuario con todo lo que hemos hecho hasta ahora:

import React, { useState } from 'react';


const FormularioAgregarUsuario = (props) => {

  const estadoInicialFormulario = { id: null, nombre: '', apellido: '' };
  const [usuario, setUsuario] = useState(estadoInicialFormulario);
    
  const gestionarCampo = (event) => {
    const { name, value } = event.target;
    setUsuario({ ...usuario, [name]: value });
  }

  return (
    <form
      onSubmit={event => {
        event.preventDefault();
        if (!usuario.nombre || !usuario.apellido) return;

        props.agregarUsuario(usuario);
        setUsuario(estadoInicialFormulario);
      }}
    >
      <div className="form-group">
        <label>Nombre</label>
        <input
          id="nombre"
          className="form-control"
          type="text"
          name="nombre"
          value={usuario.nombre}
          onChange={gestionarCampo}
        />
      </div>
      <div className="form-group">
        <label>Apellido</label>
        <input
          id="apellido"
          className="form-control"
          type="text"
          name="apellido"
          value={usuario.apellido}
          onChange={gestionarCampo}
        />
      </div>
      <div className="form-group">
        <button type="submit" className="btn btn-primary">Agregar usuario</button>
      </div>
    </form>
  )
}

export default FormularioAgregarUsuario;

Si ahora accedes al proyecto desde tu navegador, deberías ver el siguiente resultado:

Ahora ya podrás introducir nuevos usuarios. yeah!

Borrado de usuarios

Ahora vamos a agregar la funcionalidad que nos permitirá borrar usuarios de la aplicación. Para ello, primero crearemos una nueva función en el componente App, justo debajo de la función agregarUsuario. A esta función le daremos el nombre de eliminarUsuario y aceptará el id del usuario a eliminar como parámetro. La función filtrará el array con el método filter, que iterará los usuarios del array, eliminando del mismo aquellos que cumplan la condición especificada. En este caso, la condición es que el id del usuario sea el del usuario que queremos eliminar:

const eliminarUsuario = (id) => {
  setUsuarios(usuarios.filter((usuario) => usuario.id !== id));
}

Debemos pasar esta función al componente TablaUsuarios para poder asociarla con el botón de eliminación de cada usuario:

<TablaUsuarios usuarios={usuarios} eliminarUsuario={eliminarUsuario} />

Finalmente, ya solo tenemos que editar el componente TablaUsuarios para asociar la función eliminarUsuario al evento onClick de cada botón:

<button
  type="button"
  className="btn btn-primary btn-sm m-1"
  onClick={() => props.eliminarUsuario(usuario.id)}
>
  Eliminar
</button>

Ahora ya podrás eliminar usuarios de la lista:

Actualización de usuarios

Ahora vamos a ver cómo puedes actualizar los usuarios existentes. De utilizar un componente de clase, usaríamos el método componentDidUpdate para comprobar cuándo se realizan cambios. Sin embargo, en este caso usaremos una hook de efecto o effect hook, que funciona de un modo similar a los métodos componentDidMount y componentDidUpdate de los componentes de clase.

Cada vez que el usuario pulse el botón de edición de un usuario de la lista, el formulario que permite agregar usuarios pasará a ser otro que permita editar el usuario seleccionado, que contendrá los datos del mismo. Será posible enviar los datos para actualizar los datos del usuario o también salir del modo de edición. Para empezar, debemos crear un estado en el archivo App.js que nos permita definir si el modo de edición está o no activado:

const [editando, setEditando] = useState(false);

Hemos establecido el valor por defecto del estado editando como false. Además, también debemos establecer el valor inicial por defecto del formulario de edición en el mismo archivo:

const estadoInicialFormularioEdicion = { id: null, nombre: '', apellido: '' };

Necesitamos saber cuál es el formulario que estamos editando, por lo que debemos aplicar el valor inicial del estado anterior a un nuevo estado al que llamaremos usuarioActual:

const [usuarioActual, setUsuarioActual] = useState(estadoInicialFormularioEdicion);

Cuando hagamos clic en un usuario, debemos activar el modo de edición hacer que los valores de los campos del formulario sean los del usuario que estamos editando. Para lograr esto, usaremos la función editarUsuario:

const editarUsuario = (usuario) => {
  setEditando(true);
  setUsuarioActual({ id: usuario.id, nombre: usuario.nombre, apellido: usuario.apellido });
}

A continuación tenemos que pasar la función editarUsuario al componente TablaUsuarios:

<TablaUsuarios usuarios={usuarios} editarUsuario={editarUsuario} eliminarUsuario={eliminarUsuario} />

Seguidamente, edita el componente TablaUsuarios del archivo TablaUsuarios.js y ejecuta la función editarUsuario en el evento asociado a la acción onClick que agregaremos:

<button
  type="button"
  className="btn btn-primary btn-sm m-1"
  onClick={() => props.editarUsuario(usuario)}
>

Ahora debemos crear la función actualizarUsuario en el componente App, que se ejecutará cuando el formulario de edición, que todavía no hemos creado, se envíe. Esta función recorrerá el array de usuarios hasta encontrar el usuario cuyo id coincida con el que se está actualizando, modificando las propiedades nombre y apellido del mismo. La función aceptará dos parámetros; un es el id del usuario que estamos editando y el otro es un objeto que contiene los nuevos valores:

const actualizarUsuario = (id, usuarioActualizado) => {
  setEditando(false);
  const usuariosActualizados = usuarios.map((usuario) => (usuario.id === id ? usuarioActualizado : usuario));
  setUsuarios(usuariosActualizados);
}

Además, como ves, también hemos desactivado el modo de edición mediante la función setEditando.

Ahora crea el acrhivo FormularioEditarUsuario.js en el directorio /forms. Este formulario es idéntico al formulario FormularioAgregarUsuario, salvo porque en este caso estableceremos el estado desde usuarioActual a través de las propiedades del componente. También agregaremos un botón que nos permitirá cancelar el modo edición:

import React, { useState } from 'react';

const FormularioEditarUsuario = (props) => {
  const [usuario, setUsuario] = useState(props.usuarioActual);

  const gestionarCampo = (event) => {
    const { name, value } = event.target;
    setUsuario({ ...usuario, [name]: value });
  }

  return (
    <form
      onSubmit={(event) => {
        event.preventDefault();
        props.actualizarUsuario(usuario.id, usuario);
      }}
    >
      <div className="form-group">
        <label>Nombre</label>
        <input
            type="text"
            name="nombre"
            className="form-control"
            value={usuario.nombre}
            onChange={gestionarCampo}
        />
      </div>
      <div className="form-group">
        <label>Apellido</label>
        <input
            type="text"
            name="apellido"
            className="form-control"
            value={usuario.apellido}
            onChange={gestionarCampo}
        />
      </div>
      <div className="form-group">
      <button className="btn btn-danger">Actualizar usuario</button>
        <button
          className="btn btn-primary ml-2"
          onClick={() => props.setEditando(false)}
        >
            Cancelar
        </button>
      </div>
    </form>
  )
}

export default FormularioEditarUsuario;

Seguidamente, importa el componente FormularioEditarUsuario en el componente App:

import FormularioEditarUsuario from './forms/FormularioEditarUsuario';

Ahora debemos agregar un switch que permita alternar entre el formulario de edición y el formulario que permite agregar usuarios, intercambiando ambos componentes en función del estado editando. Si el valor de editando es false, mostraremos el componente FormularioAgregarUsuario. De lo contrario, mostraremos el componente FormularioEditarUsuario. Por lo tanto, debes editar el contenido de la sentencia return del componente App tal que así:

<div className="container">
  <h1>Tutorial React Hooks</h1>
  <div className="row"> 
    {editando ? (
      <div className="col-md-4">
        <h2>Editar usuario</h2>
        <FormularioEditarUsuario
          setEditando={setEditando}
          usuarioActual={usuarioActual}
          actualizarUsuario={actualizarUsuario}
        />
      </div>
    ) : (
      <div className="col-md-4">
        <h2>Agregar usuario</h2>
        <FormularioAgregarUsuario agregarUsuario={agregarUsuario} />
      </div>
    )}
    <div className="col-md-4">
      <h2>Ver usuarios</h2>
      <TablaUsuarios usuarios={usuarios} editarUsuario={editarUsuario} eliminarUsuario={eliminarUsuario} />
    </div>
  </div>
 </div>

Además, debemos modificar la función eliminarUsuario del componente App y usar la función setEditing pasándose el valor false, de modo que salga del modo de edición en caso de que se elimine el usuario que se está editando:

const eliminarUsuario = (id) => {
  setUsuarios(usuarios.filter((usuario) => usuario.id !== id));
  setEditando(false);
}

Ahora ya deberías poder editar los usuarios de la lista. Si ves la aplicación en tu navegador, deberías ver algo así:

Sin embargo, todavía no hemos terminado, ya que en el momento que estás editando un usuario, no podrás comenzar a editar otro a no ser que canceles la edición actual. Para solucionarlo usaremos las hooks de efecto.

Usando Hooks de efecto

Tal y como está la aplicación, no es posible cambiar de usuario una vez estás editando uno de ellos. Cuando el componente FormularioEditarUsuario se está mostrando, no se pasa el estado desde el componente App al componente FormularioEditarUsuario mediante las propiedades. Para solucionarlo podemos usar hooks de efecto.

Lo que queremos lograr es que el componente FormularioEditarUsuario reciba la información de que las propiedades han cambiado. En un componente de clase usaríamos el método componentDidUpdate, pero no está disponible en los componentes funcionales.

Lo primero que haremos será importar useEffect desde la librería de React en el componente FormularioEditarUsuario:

import React, { useState, useEffect } from 'react';

Luego debemos usar la función la función useEffect, que acepta como parámetro una función callback que actualiza el estado usuario con el usuario actual. En la función callback usaremos la función setUsuario, a la que le pasaremos la propiedad usuarioActual como parámetro:

useEffect(() => {
  setUsuario(props.usuarioActual);
}, [props]);

No es necesario que comprobemos si el usuario que se envía desde al componente App es el mismo que se está editando, ya que esto es lo que haríamos en un componente funcional en caso de no usar useEffect. Actualmente ya que están observando dichas propiedades.

Usando Hooks de contexto

También es posible usar estados globales que puedes compartir entre tus componentes, útil en caso de que no quieras pasar ciertas variables como una propiedad. Esto es posible mediante el uso de la hook useContext y otras técnicas de la Context API de React.

Para aprender a usar useContext, consulta el siguiente tutorial, en el que explico cómo usar la Context API en React:

Finalizando

Y con esto ya hemos terminado la aplicación. Puedes ver la aplicación en funcionamiento en este enlace y también puedes encontrar el código completo en GitHub.

No hemos usado todas las funcionalidades de las hooks de React, pero sí las funciones más comunes, que son las que encontrarás en la mayor parte de proyectos. Si tienes dudas o quieres aprender más cosas acerca de las Hooks, consulta los siguientes enlaces:

Y esto ha sido todo.


Avatar de Edu Lazaro

Edu Lázaro: Ingeniero técnico en informática, actualmente trabajo como desarrollador web y programador de videojuegos.

👋 Hola! Soy Edu, me encanta crear cosas y he redactado esta guía. Si te ha resultado útil, el mayor favor que me podrías hacer es el de compatirla en Twitter 😊

Si quieres conocer mis proyectos, sígueme en Twitter.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

“- Hey, Doc. No tenemos suficiente carretera para ir a 140/h km. - ¿Carretera? A donde vamos, no necesitaremos carreteras.”