0% encontró este documento útil (0 votos)
12 vistas60 páginas

Primeros Pasos en JavaScript

Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
12 vistas60 páginas

Primeros Pasos en JavaScript

Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 60

Primeros pasos en JavaScript

En el contexto de JavaScript y el desarrollo web, los términos "librería",


"biblioteca" y "script" tienen significados específicos, que son importantes para
entender cómo se organizan y se utilizan los recursos de código:

1. Librería

Una librería (o biblioteca) es un conjunto de funciones y objetos predefinidos que proporcionan


funcionalidades específicas para facilitar el desarrollo de aplicaciones. En el contexto de
JavaScript, una librería suele ofrecer utilidades, herramientas y componentes reutilizables que
podemos integrar en los proyectos para evitar tener que escribir código desde cero.

Ejemplos:

jQuery: Facilita la manipulación del DOM y la gestión de eventos.

Lodash: Ofrece utilidades para trabajar con arrays, objetos y otras estructuras de datos.

Axios: Facilita la realización de solicitudes HTTP.

2. Biblioteca

En términos generales, el término "biblioteca" y "librería" se usan de manera intercambiable,


pero a veces "biblioteca" se refiere a un conjunto más amplio de recursos. En algunos contextos,
una biblioteca puede incluir una serie de archivos de código (scripts) y documentación que
proporcionan funcionalidades específicas.

Ejemplos:

React: Aunque a veces se llama librería, es una biblioteca para construir interfaces de
usuario.

Three.js: Biblioteca para gráficos 3D en JavaScript.

3. Script

Un script en JavaScript es un archivo que contiene código JavaScript que se ejecuta en el


navegador o en un entorno de servidor. Los scripts pueden ser tan simples como un pequeño
fragmento de código que realiza una tarea específica o tan complejos como una aplicación
completa.

Ejemplos:

 Un script para validar formularios: Un archivo JavaScript que valida la entrada del
usuario en un formulario.
 Un script para realizar animaciones: Código JavaScript que anima elementos en una
página web.

Características:

 Tamaño y Complejidad: Los scripts pueden variar en tamaño desde unas pocas líneas
hasta archivos grandes con múltiples funciones.

 Ejecución: Se ejecutan en el contexto de una página web (en el navegador) o en el


servidor (si se usa Node.js).

Diferencias
 Librería: Conjunto de funcionalidades y herramientas reutilizables. Ejemplo: jQuery,
Lodash.

 Biblioteca: Término similar a librería, a menudo usado para describir un conjunto más
completo de recursos y módulos. Ejemplo: React, D3.js.

 Script: Archivo con código JavaScript que puede realizar una variedad de tareas.
Ejemplo: Un archivo que gestiona la lógica de un formulario.

Vite

Es una herramienta de entorno de desarrollo y compilación (build tool) para


proyectos de JavaScript, diseñada para mejorar la experiencia de desarrollo en
comparación con herramientas tradicionales como Webpack. Creada por Evan You, el
mismo creador de Vue.js, Vite está enfocada en proporcionar una experiencia rápida y
moderna para el desarrollo frontend.

Para crear la aplicación react utilizando vite

1. Instalar Vite globalmente: Abrimos la terminal y ejecutamos el siguiente comando


para instalar Vite globalmente:

npm create vite@latest fundamentos-react -- --template react

A veces ocurre un error por no estar añadido Node.js nmp al PATH


npm create vite@latest: Esto invoca el comando de create del paquete vite a través
de npm. vite@latest asegura que estás utilizando la versión más reciente de Vite.

nombre-proyecto: Este es el nombre del directorio o carpeta donde se creará el nuevo


proyecto. Puedes reemplazar nombre-proyecto con el nombre que desees para tu
proyecto.

-- --template react: Aquí es donde se especifica el tipo de plantilla que quieres usar.
react indica que deseas configurar un proyecto que usa React como librería de interfaz
de usuario.

React Js empezará a crear todos los ficheros que necesita para poder ser ejecutada,
razón por la cual tarda unos minutos.

2. Ingresamos al proyecto

Después de instalada la aplicación, abrimos la aplicación que creamos

cd fundamentos-react

3. Instalación de las dependencias del proyecto:

Las dependencias son recursos que se usan, como, como librerías externas que se
pueden encontrar en el archivo package.json y con la ayuda de npm se instalan con el
fin de tener acceso a ellas en toda la aplicación.

npm install

Luego de creada la aplicación se corre el comando npm run dev para verificar su
funcionamiento en el servidor local:

npm run dev


Si todo quedo correcto aparece el mensaje

Para comprobar que todo esté correcto, se abre en el navegador favorito (Chrome
preferiblemente) la siguiente url: http://localhost:5173/

Para abrir el proyecto en Visual Studio Code, se elige, en la página principal, la opción “Start” en
este caso deseamos dar en “Open”

Nos ubicamos en la carpeta CRS

4. Rutas

Para este proyecto se usará React Router que consiste en una librería que permite navegar
entre páginas y rutas que se han creado en la aplicación de React.

Es útil especialmente en las aplicaciones de una sola página (SPA:

a. Para la instalación se abre una nueva terminal en Visual Studio Code, se detiene el
servicio que estaba corriendo con las teclas ctrl + c y se procede a instalar la librería:
npm install react-router-dom
b. Se vuelve a correr la aplicación con el siguiente comando:

npm run dev

c. En el archivo main.jsx se configuran las rutas necesarias para el proyecto, en


este caso se agregan dos rutas: la ruta principal: http://localhost:5173/ y la ruta
de bienvenida: http://localhost:5173/welcome, utilizando una etiqueta h1 propia
de html y se escribe un texto de bienvenida al módulo.

Cuando abrimos el archivo main.js, se tiene configurado lo siguiente:

d. Seguidamente se importan dos dependencias necesarias para hacer uso de la


navegación:
import {
createBrowserRouter,
RouterProvider
} from "react-router-dom";

Quedaría de la siguiente manera::

createBrowserRouter es una función proporcionada por la biblioteca react-router-


dom que se utiliza para crear una instancia de un enrutador basado en el navegador.
Esta función es parte de la versión 6 de react-router-dom, que introduce una nueva
API más moderna y eficiente para la gestión de rutas en aplicaciones React.

RouterProvider es un componente proporcionado por la biblioteca react-router-dom


que se utiliza para integrar un enrutador configurado en una aplicación React. Es un
componente clave en la configuración de enrutamiento cuando se usa la API
moderna de enrutamiento, especialmente con createBrowserRouter en la versión 6
de react-router-dom.

from 'react-router-dom'; se utiliza en un archivo de JavaScript o TypeScript para


importar funciones y componentes específicos de la biblioteca react-router-dom,
que es una biblioteca popular para la gestión de enrutamiento en aplicaciones
React.

e. Luego se crea una función llamada router a la cual se le agregan las rutas
necesarias para el proyecto, en este caso la ruta inicial path: "/" y una segunda
ruta path: "welcome".

const router = createBrowserRouter([


{
path: "/",
element: <App />,
},
{
path: "welcome",
element: <h1>Tecnologias Emergentes</h1>,
}
]);
Este código configura un enrutador que renderiza diferentes componentes o elementos
en función de la URL en la que se encuentre el usuario. Si la URL es la raíz ("/"), se
mostrará el componente <App />. Si la URL es "/welcome", se mostrará un título con el
texto "Tecnologias Emergentes".

f. Ahora para hacer uso de esta función router se pasa como parámetro a la
dependencia RouterProvider importada:

ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<RouterProvider router={router}/>
</React.StrictMode>
)

El archivo main.jsx quedaría así:


 Guardamos y corremos nuevamente la aplicación con el comando npm run dev,
verificamos en el navegador ambas rutas.

Nota:

 En este punto, ya se tienen las rutas para usar en la aplicación. En la dirección


http://127.0.0.?:517? se verá la siguiente pantalla:
 Y en la dirección http://127.0.0.?:517?/welcome se verá un mensaje de bienvenida a Tecnologías Emergentes.

Ver video Rutas.(Para ampliar información)

5. Creación de página para la ruta Welcome

a. Se crea una carpeta dando click en la parte superior izquierda de Visual Studio. Aparece un
icono con una carpeta y la opción de agregar un nombre a la carpeta, la cual se llamará pages.

b. Dentro de la carpeta páginas se crea un archivo llamado Welcome.jsx

Es importante que la primera letra del nombre de la función esté en mayúscula, como en el ejemplo:
Welcome.

C. Proseguimos a crear la estructura de la página. (Abrimos el archivo Welcome.jsx) y


creamos la estructura con el siguiente código

import React from 'react'


const Welcome = () => {
return (
<div>Welcome</div>
)
}
export default Welcome

c. Abrimos el archivo main.jsx y (En lugar de tener <h1> en el main.jsx se puede importar la
página creada)

Primero se importa la página Welcome: para ello, insertamos la siguiente línea de código

import Welcome from './pages/Welcome';

Luego se usa en el element de la ruta <Welcome /> y de esta forma si se dirige a nuestra
ruta: http://127.0.0.?:517?/welcome, se tendrá el mensaje Welcome del div que se ha creado:
Probamos en el navegador que esté funcionando correctamente

6. Componentes

Los componentes son parte esencial de React Js. porque son la base para construir las
interfaces dinámicas para los usuarios finales.

Con las etiquetas de Html se pueden crear secciones estructuradas para darle contenido
a la página tales como: <section>, <h1>, <table>, <p>, <img> entre muchas otras
etiquetas que se pueden usar.

Para llevar esta sección de Html a React se crea una carpeta para los componentes
llamada components

Ubicados en src creamos la carpeta components

Dentro de components se crea un archivo llamado Profile.jsx,

Abrimos este archivo Profile.jsx y creamos la estructura de un archivo. Jsx


import React from 'react'
const Profile = () => {
return (
<div>Profile</div>
)
}

export default Profile

Para el componente se va a crear un perfil de usuario con imagen, titulo, texto y un


botón. Para ello insertamos el siguiente código. (Archivo Profile.jsx)

import React from 'react'


const Profile = () => {
return (
<div>
<img src="https://media.gq.com.mx/photos/620e915c43f71a078a35533f/16:9/w_1600,c_limit/playa.jpg"
alt="profile" />
<h1>Mi primer componente de React</h1>

<p>Shoulder drumstick leberkas velit ad ground round. Jowl voluptate pork chop ham hock veniam reprehenderit pork
loin minim.</p>
<button>Compartir</button>
</div>
)
}

export default Profile

import React from 'react'


const Profile = () => {
return (
<div>
<img src="https://cdn.pixabay.com/photo/2022/11/09/01/59/profile-7579739_1280.jpg"
alt="profile" />
<h1>Componente de React configurado</h1>

<p>Shoulder drumstick leberkas velit ad ground round. Jowl voluptate pork chop ham hock
veniam reprehenderit pork loin minim.</p>

<button>Compartir</button>
</div>
)
}

export default Profile

Pero aún no se puede ver reflejada esta información, porque es necesario ir a la página
Welcome.jsx para importar el componente ya creado.

import Profile from '../components/Profile'

Quedaría así

import React from 'react'


import Profile from '../components/Profile'

const Welcome = () => {


return (
<Profile />
)
}

export default Welcome


Verificamos que esté funcionando correctamente en el navegador, ejecutando el
comando respectivo.

7. Estilos

En una aplicación de React, hay varias formas de agregar estilos a los componentes. Cada
método tiene sus propias ventajas y casos de uso. Principales formas de aplicar estilos en React:

 CSS Clásico (Archivos CSS)

Puedes usar archivos CSS tradicionales para estilizar tus componentes. Los estilos se definen en
archivos .css y se importan en los componentes.

Ventajas:

 Familiar y ampliamente usado.


 Compatible con la mayoría de las herramientas y frameworks.

Cómo hacerlo:

1. Crea un archivo CSS: Por ejemplo, App.css.

2. Importa el archivo CSS en tu componente:


 CSS Modules

Los CSS Modules permiten que los estilos sean locales a un componente, evitando problemas de
colisión de nombres.

Ventajas:

 Estilos encapsulados por componente.


 Evita conflictos globales de CSS.

Cómo hacerlo:

1. Crea un archivo CSS Module: Usa la extensión .module.css, por ejemplo,


App.module.css.

2. Importa el archivo CSS Module en tu componente:


 Styled Components

Styled Components es una librería que permite escribir estilos en JavaScript usando una sintaxis
similar a CSS. Los estilos se definen como componentes React.

Ventajas:

 Escopado de estilos por componente.


 Soporte para temas y anidación.

Cómo hacerlo:

1. Instala styled-components:

Define y usa un componente estilizado:


 Emotion

Emotion es otra librería CSS-in-JS que permite escribir estilos en JavaScript con soporte
para temas y estilos dinámicos.

Ventajas:

 Alta performance.
 Soporte para temas y estilos dinámicos.

Cómo hacerlo:

1. Instala @emotion/react y @emotion/styled:

2. Define y usa estilos con Emotion:

 Inline Styles

Los estilos en línea se definen directamente en el atributo style del JSX.

Ventajas:

 Ideal para estilos que cambian dinámicamente.


Cómo hacerlo:

 Tailwind CSS

Tailwind CSS es un framework de utilidades que proporciona clases CSS predefinidas para
construir diseños sin necesidad de escribir CSS personalizado.

Ventajas:

 Diseño basado en utilidades.


 Aumenta la velocidad de desarrollo.

Cómo hacerlo:

1. Instala Tailwind CSS:

2. Configura Tailwind en tu proyecto: Añade Tailwind a tu archivo CSS global.


3. Usa clases de Tailwind en tu componente:

En conclusión:

 CSS Clásico: Usar archivos .css para aplicar estilos globales o locales.
 CSS Modules: Encapsula estilos en componentes para evitar conflictos.
 Styled Components y Emotion: Permiten escribir estilos en JavaScript con soporte para
temas y dinámicas.
 Inline Styles: Aplicar estilos directamente en el atributo style de JSX.
 Tailwind CSS: Utiliza clases de utilidades para construir estilos rápidos y responsivos.

Cada enfoque tiene sus ventajas, y la elección del método depende de tus necesidades
específicas y preferencias de desarrollo.

Vamos a utilizar framework de código abierto Tailwind CSS, herramienta que ofrece clases de
estilos predefinidas, en la que se puede estimar botones, formularios, secciones, hasta crear
componentes de mayor complejidad que con Tailwind, lo cual puede ser más sencillo y eficiente.

Configuración:
1. Se eliminan los archivos que por defecto vienen con la instalación de Vite + React

Con click derecho en el archivo de App.css se tiene la opción de eliminarlo.

 Para evitar un error al momento de correr la aplicación se abre el archivo App.jsx y se elimina la línea:
import './App.css' porque se estaría importando un archivo css que no existe.
 Instalación de Tailwind

En la terminal Visual Studio Code se instala tailwindcss

npm install -D tailwindcss postcss autoprefixer

La letra -D indica que la dependencia se va a instalar sólo para entornos de desarrollo.

Se inicializa

npx tailwindcss init

Si se revisa el archivo package.json se observa que la dependencia tailwindcss ha sido instalada


correctamente.

 Se inicializa el proyecto con Tailwind CSS y así crear los archivos de configuración
necesarios para su uso. Para ello en la consola ejecutamos el siguiente comando:

npx tailwindcss init -p

npx: Es una herramienta que viene con Node.js y que permite ejecutar paquetes de npm sin
necesidad de instalarlos globalmente en tu sistema. Es útil para ejecutar comandos de
herramientas que no necesitas instalar permanentemente.

tailwindcss: Es el nombre del paquete de Tailwind CSS. Al usar npx, estás diciendo que quieres
ejecutar el paquete de Tailwind CSS.

init: Es el comando que indica a Tailwind CSS que genere archivos de configuración
predeterminados.

-p: Es una opción que se utiliza para crear un archivo postcss.config.js junto con el archivo
tailwind.config.js. El archivo postcss.config.js se utiliza para configurar PostCSS, una
herramienta de procesamiento de CSS que puede utilizarse para agregar características
adicionales a tu CSS.
Cuando ejecutas npx tailwindcss init -p, se crean dos archivos en tu proyecto:

 tailwind.config.js: Este archivo es donde puedes personalizar la configuración de Tailwind


CSS, como los colores, fuentes y otros aspectos del diseño.
 postcss.config.js: Este archivo es para configurar PostCSS, que trabaja junto con Tailwind
CSS para procesar el CSS.

Estos archivos te permiten personalizar y configurar Tailwind CSS según las necesidades de tu proyecto.

 Dentro del archivo tailwind.config.cjs se agrega la siguiente configuración (estructura de la


pagina):

/** @type {import('tailwindcss').Config} */


module.exports = {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}

 En el archivo index.css se elimina todo lo que haya en su interior y se agregan las


siguientes dependencias:

@tailwind base;
@tailwind components;
@tailwind utilities;

@tailwind base;: Incluye estilos base predeterminados de Tailwind CSS.

@tailwind components;: Incluye estilos de componentes reutilizables.

@tailwind utilities;: Incluye clases de utilidades para estilos específicos.

 Abrimos el archivo Profile.jsx y se agrega el primer estilo css a la etiqueta H1


<h1 className="text-3xl font-bold underline">Mi primer componente de React</h1>

Quedaría así

En React Js las clases de los elementos cambian a className y en este ejemplo se observa
cómo con 3 tipos de clases se agregan al elemento h1.

En comparación con el Html y CSS tradicional seria de la siguiente manera:

<h1 class="title">Mi primer componente de React</h1>

.title: {
font-weight: 700;
font-size: 1.875rem;
line-height: 2.25rem;
text-decoration-line: underline;
}

Se corre el proyecto (npm run dev)


 Ahora procedemos a aplicar estilos o mejorar el diseño visual del componente
<Profile /> para que se vea mucho mejor:

Se inicia creando una etiqueta <div> que encierre todo el contenido, de la siguiente forma:

A la etiqueta <div> se le agregan clases de tailwind para crear un diseño del componente
Profile.

Con esas clases se está creando un máximo del ancho, redondeando las esquinas superiores e
inferiores del elemento y agregando sombras alrededor del div.

 Ahora dentro del div se agrega una imagen con el máximo de ancho del elemento <div>

<img className="w-full" src="https://media.gq.com.mx/photos/620e915c43f71a078a35533f/16:9/


w_1600,c_limit/playa.jpg" alt="profile" />

 Dentro de la imagen se crea otro <div> agregando padding para darle espacio a los
elementos.

<div className="px-6 py-4">


</div>

Así vamos

 Dentro del <div> que acabamos de crear se adicionan dos párrafos como título y subtítulo.

<p className="font-bold text-xl mb-2">Mi primer componente de React</p>


<p className="text-gray-700 text-base">
JavaScript es un lenguaje de programación interpretado, dialecto del estándar ECMAScript. Se define
como orientado a objetos, basado en prototipos, imperativo, débilmente tipado y dinámico
</p>
Así vamos, observamos en la imagen de referencia, como es importante prestar atención a la
sangría.

 Por último, se agrega otro <div> con márgenes para darle espacio al botón.

<div className="px-6 pt-4 pb-2">


<button className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-
700 mr-2 mb-2">Compartir</button>
</div>

Así quedaría
Guardamos y visualizamos en el navegador como vamos:

7. Props (properties) - Propiedades

Los componentes permiten separar toda la interfaz de usuario en elementos que son
reutilizables y con los props se logra que cada una de estas piezas tengan un contenido
diferente y dinámico. Los props son una forma de pasar datos de un componente a otro en
React.

 Abrimos la página Welcome en un <div> se encierran 3 componentes de <Profile> al <div>


se le agregan los siguientes estilos para centrar nuestro contenido:

<div className='flex gap-4 justify-center mt-6'>


<Profile />
<Profile />
<Profile />
</div>
Con estos 3 componentes iguales, se pueden cambiar las imágenes para que sean diferentes sin
necesidad de crear nuevos componentes, para ello se utilizan los props.

A cada componente se le asigna una propiedad llamada image y se envía a cada una la url de la
imagen que se desea cambiar. A cada componente Profile se propiedad llamada image.

Import React from 'react'

import Profile from '../components/Profile'

const Welcome = () => {

return (
<div className='flex gap-4 justify-center mt-6'>
<Profile image="https://cdn.pixabay.com/photo/2023/01/19/10/24/castle-7728772_1280.jpg" />
<Profile image="https://cdn.pixabay.com/photo/2023/01/22/15/16/ocean-7736669_1280.jpg" />
<Profile image="https://cdn.pixabay.com/photo/2023/01/25/18/14/landscape-7744216_1280.jpg" />
</div>
)
}

export default Welcome


 Ahora abrimos el componente <Profile /> Profile.jsx

 Asignamos como parámetro recibir unos props y se ponen en un console.log para ver que
contiene esta propiedad:

 Se inspecciona la página y para ver que en props se tiene un objeto de tipo { image: “https:
…” } con la url de la imagen.

 En el componente <Profile> en la etiqueta <img> exactamente en el src se agrega la


propiedad props.image

src={props.image}
Observamos que ahora el componente tiene imágenes diferentes

PRIMER RETO:

1. Cambie los títulos y párrafos de forma dinámica.

Formulario

En la vista Welcome.jsx se cambian los estilos del primer div para dividir la vista en dos
columnas y tener en un apartado la tarjeta y en el otro apartado un formulario.

 Creamos el apartado para la tarjeta:

Se crea un <div> y se le agrega la siguiente clase: <div className="flex justify-center


mt-6">
El componente Profile se encierra en otro <div> con la clase: <div className='w-1/3'>
quedando de la siguiente forma:

<div className="flex justify-center mt-6">


<div className='w-1/3'>
<Profile image="https://cdn.pixabay.com/photo/2023/01/19/10/24/castle-7728772_1280.jpg" />
</div>
</div>

 Ahora vamos a crear el espacio para el formulario:

Se crea otra clase igual al <div> que encierra el componente <Profile>:

<div className='w-1/3'>

</div>
Para la creación del formulario se usa la etiqueta form de html para encerrar los inputs que se
van a manejar.

<form className='px-8 py-4 border rounded-md'> a este form se le agregan clases para tener
un border y darles un espacio a los elementos del interior.

Dentro del formulario se usa la etiqueta <span> para indicarle al usuario que información exacta
va a ingresar.

<span className="block text-sm font-medium text-slate-700">Name</span>

Después de la etiqueta <span> se usa la etiqueta <input> de Html para crear campos de texto
en los que el usuario puede ingresar su información.

<input type="text" className="px-4 py-2 border rounded-md w-full" placeholder='Name'/>

Guardamos y verificamos en el localhost que se hayan generado los cambios en la página


welcome.
 Se prosigue a agregar más campos al formulario con el fin de recolectar la información
necesaria:

● Last Name → tipo texto

● Age → tipo rango

● Profile Picture → tipo archivo

<form className='px-8 py-4 border rounded-md'>

<span className="block text-sm font-medium text-slate-700">Name</span>


<input type="text" className="px-4 py-2 border rounded-md w-full" placeholder='Name'/>

<span className="block text-sm font-medium text-slate-700 mt-6">Last name</span>


<input type="text" className="px-4 py-2 border rounded-md w-full" placeholder='Last Name'/>

<span className="block text-sm font-medium text-slate-700 mt-6">Age</span>


<input type="range" className="px-4 py-2 border rounded-md w-full" placeholder='Age'/>

<span className="block text-sm font-medium text-slate-700 mt-6">Profile picture</span>


<input type="file" className="px-4 py-2 border rounded-md w-full" placeholder='Profile picture' />

</form>

 Por último, se adiciona un botón de confirmación.

<div className='mt-8'>
<button className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold
text-gray-700 mr-2 mb-2">Save</button>
</div>
¡Como resultado se obtiene una tarjeta con un formulario en el que se puede empezar a darle
vida a la aplicación!

8. Eventos de JavaScript

JavaScript dispone de una gran cantidad de eventos que se pueden usar para llevar el control de
la aplicación, como, por ejemplo:

● onClick: este evento se activa cuando un usuario hace click sobre alguna etiqueta como
un botón, un anchor, una imagen o un div para ejecutar una función en la que se obtenga
un resultado.

● onChange: este evento se activa principalmente cuando se desea obtener la información


que el usuario ha ingresado en un input de un formulario.

● onSubmit: su principal uso está en los formularios al momento de ingresar todos los
datos necesarios y activar el botón de enviar para que los datos sean ingresados a una
base de datos o realizar alguna otra funcionalidad.

● onFocus: este evento se activa cuando se selecciona un input del formulario.


En el siguiente ejemplo al seleccionar el input se obtiene un borde azul:

● onBlur: Este evento se activa cuando dejamos de seleccionar el input.

En este ejemplo al dar click en alguna parte exterior del input el borde azul desaparece:

SEGUNDO RETO:

Consultar otros eventos y asignarlos

 Asignamos el envento onMouseEnter a la imagen.

Abrimos Profile.jsx y aspignamos el evento a la imagen, para que cuando se pase el mouse
sobre ella aparezca un mensaje

<img className="w-full" src={props.image} alt="profile" onMouseEnter={()=>


alert("Imagen ilustrada")}/>
9. Hooks de react "enganchar"

Los Hooks son funciones que permiten “enganchar” el estado de React y el ciclo de vida
desde componentes de función (es.reactjs.org/, s.f. p. 9).

Un Hook en React es una función especial que te permite "enganchar" (de ahí el
nombre "hook") características de React, como el estado y el ciclo de vida, en
componentes funcionales. Antes de los Hooks, estas características solo estaban
disponibles en componentes de clase. Los Hooks permiten usar estas funcionalidades en
componentes funcionales, que son generalmente más concisos y fáciles de entender.

Tipos Principales de Hooks

1. useState

 Qué Hace: Permite agregar estado a un componente funcional.


 Cómo Se Usa: Declara una variable de estado y una función para actualizar ese estado.

Este hook permite agregar estados a una aplicación con el fin de modificar textos, arreglos,
datos lógicos (booleanos), objetos, entre otros.

Para hacer uso del hook se crea una constante y dentro de un arreglo, como primer elemento,
se tiene el valor que va a ser modificado y como segundo elemento la función que va a modificar
el primer valor, seguido de la igualdad, para lo cual se usa el hook de react useState(false)
donde se inicia el valor en falso const [showStudent, setShowStudent] = useState(false);

Importante: Para usar el hook de useSate es necesario importar de la librería de react:

import React, { useState } from 'react';

 Creamos un nuevo componente llamado Excer.jsx


Creamos la estructura de la página

import React, { useState } from 'react';

const Excer= () => {

const [isStudent, setIsStudent] = useState(false);

return (
<div className='m-10'>
<button
type="button"
className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2"
onClick={() => setIsStudent(true)}
>
Show text
</button>
{
isStudent && <p>Welcome 😃</p>
}
</div>
);
}

export default Excer;

import React, { useState } from 'react'; Primero se importa la librería React y el hook
useState. useState es un hook que permite añadir estado a los componentes funcionales en
React.

const Excer = () => { Definición del Componente Excer

Uso del Hook useState:

· useState(false) inicializa una variable de estado isStudent con un valor inicial de false.
· isStudent es la variable que guarda el estado actual.

· setIsStudent es una función que permite actualizar el estado.

return ( Renderización del Componente:

· <div className='m-10'>: Un contenedor <div> con una clase de estilo.

· <button>: Un botón con estilo, que al ser clicado ejecuta la función onClick.

 onClick={() => setIsStudent(true)}: Cuando el botón es clicado, se llama a


setIsStudent(true), lo que cambia el valor de isStudent a true.

· {isStudent && <p>Welcome 😃</p>}: Esta es una expresión condicional en JSX. Si isStudent
es true, se renderiza el párrafo <p>Welcome 😃</p>. Si isStudent es false, el párrafo no se
renderiza.

Este componente muestra un botón y, cuando se hace clic en él, cambia el estado isStudent a
true. Al hacerlo, se muestra el mensaje "Welcome 😃" debajo del botón. La lógica principal aquí
está en el uso del hook useState para manejar el estado del componente y en la renderización
condicional del mensaje basado en ese estado.

 Creamos una nueva ruta llamada excer para acceder a la pagina creada.

Abrimos el archivo main.jsx y creamos la nueva ruta.

Primero la importamos

{
path: “excer”,

Element:<Excer/>

Como primera instancia se tiene el botón de ver texto (Show text).


2. useEffect

Otro tipo de Hook que ermite ejecutar efectos secundarios en componentes funcionales, como fetch de datos,
suscripciones o manipulación del DOM.

 Cómo Se Usa: Acepta una función que se ejecuta después de que el componente se
renderiza.

3.useContext

Otro tipo de Hook que permite acceder al contexto en componentes funcionales.

 Cómo Se Usa: Lee el valor de un contexto definido en algún lugar superior en la


jerarquía de componentes.

4. useReducer

Es una alternativa a useState para manejar estados más complejos, donde el siguiente estado
depende del anterior.

 Cómo Se Usa: Usa un reductor (una función que recibe el estado actual y una acción y
devuelve el nuevo estado) para actualizar el estado.

5. useMemo

Memoriza el resultado de una función para evitar cálculos innecesarios si las dependencias no
cambian.

 Cómo Se Usa: Recibe una función y un array de dependencias.

6. useCallback

Memoriza una función para evitar que se cree una nueva instancia de la función en cada
renderizado.

 Cómo Se Usa: Recibe una función y un array de dependencias.


En resumen los Hooks son funciones que permiten usar el estado y otras características de
React en componentes funcionales.

Los Hooks más comunes son useState, useEffect, useContext, useReducer, useMemo y
useCallback.

Los Hooks permiten escribir componentes más simples y reutilizables al evitar la complejidad de
las clases.

TERCER RETO:

3. Crear otro botón que esconda el mensaje Welcome 😃

useEffect

El hook useEffect se ejecuta después del primer renderizado de la aplicación y por lo tanto se
pueden crear acciones, requeridas en primera instancia, sin necesidad de hacer click en botones
o esperar a llamar una acción para poder ser ejecutada.

 Se invoca el método useEffect de react

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

y el método recibe una función en la que se puede crear la lógica para cambiar estados y
llamadas a servicios externos.

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

const Exc = () => {


const [isStudent, setIsStudent] = useState(false);

useEffect(() => {
// code here
console.log('Me ejecuto despues del primer render de la aplicación');
}, [])

return (
<div className='m-10'>
<button
type="button"
className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700
mr-2 mb-2"
onClick={() => setIsStudent(true)}
>
Show text
</button>
{
isStudent && <p>Welcome 😃</p>
}
</div>
);
}

export default Excer;

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

// Definición del componente funcional Excer

const Excer = () => {

// Inicializa el estado 'isStudent' con el valor inicial 'false'

const [isStudent, setIsStudent] = useState(false);

// useEffect para manejar el temporizador cuando el estado 'isStudent' cambia

useEffect(() => {

let timer;

// Si 'isStudent' es verdadero, establece un temporizador para ocultar el mensaje

if (isStudent) {

timer = setTimeout(() => {

setIsStudent(false); // Oculta el mensaje después de 5 segundos


}, 5000); // 5000 milisegundos = 5 segundos

// Cleanup function para limpiar el temporizador si el componente se desmonta

return () => clearTimeout(timer);

}, [isStudent]); // Dependencia en 'isStudent', el efecto se ejecuta cuando 'isStudent'


cambia

return (

<div className='m-10'>

{/* Botón para mostrar el texto */}

<button

type="button"

className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold


text-gray-700 mr-2 mb-2"

onClick={() => setIsStudent(true)} // Al hacer clic, se establece 'isStudent' a true

>

Show text

</button>

{/* Botón para ocultar el texto */}

<button

type="button"

className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold


text-gray-700 mb-2"

onClick={() => setIsStudent(false)} // Al hacer clic, se establece 'isStudent' a


false

>

Hide text

</button>

{/* Renderiza el mensaje 'Welcome 😃' solo si 'isStudent' es true */}

{isStudent && <p>Welcome 😃</p>}

</div>
);

export default Excer;

10. Eventos de JavaScript + Hooks + Formulario + Tarjeta

Después de darle una revisada a algunos conceptos de React se puede darle vida al formulario y
a la tarjeta para que interactúen en conjunto

Se crea una función handleChange para obtener la información que el usuario va escribiendo en
cada uno de los campos, esta función recibe como parámetro un evento con todas las acciones
que el usuario ha ingresado.

Para ver la información de este parámetro en el campo “Name” se ****agrega el evento


onChange:

 Abrimos el archivo Welcome.jsx

const handleChange = (event) => {


console.log('event===>', event);
}

Al dirigirse a la aplicación e inspeccionar el elemento, cada vez que se ingresa una letra aparece
por consola un objeto.
Al abrir el objeto se tienen diferentes propiedades que se pueden usar en el momento que sean
requeridas, la que es importante en este caso es target

En target se tiene el valor del campo ingresado (”F”)

Al momento de escribir el nombre completo en el target value está el nombre completo


 Se requiere crear el código en un useState para almacenar esta información.

En el archivo Welcome.jsx. Se ingresan el siguiente código

1. Importa el useState de react

import React, { useState } from 'react'

1. Crea el hook useState (se inicializa con un string vacío ‘’)

const [name, setName] = useState('');

1. En la función se actualiza el name por medio de setName

setName(event.target.value);

1. El nombre se pasa como props en la tarjeta

<Profile name={name} />

Welcome.jsx (Lineas en color rojo)

import React, { useState } from 'react'


import Profile from '../components/Profile'

const Welcome = () => {


const [name, setName] = useState('');

const handleChange = (event) => {


setName(event.target.value); (Borra la impresion de consola)
}

return (
<div className="flex justify-center mt-6">
<div className='w-1/3'>
<Profile image="https://cdn.pixabay.com/photo/2023/01/19/10/24/castle-7728772_1280.jpg"
name={name} />
</div>

<div className='w-1/3'>
<form className='px-8 py-4 border rounded-md'>

<span className="block text-sm font-medium text-slate-700">Name</span>


<input type="text" className="px-4 py-2 border rounded-md w-full" placeholder='Name'
onChange={handleChange} />

<span className="block text-sm font-medium text-slate-700 mt-6">Last name</span>


<input type="text" className="px-4 py-2 border rounded-md w-full" placeholder='Last Name'/>

<span className="block text-sm font-medium text-slate-700 mt-6">Age</span>


<input type="range" className="px-4 py-2 border rounded-md w-full" placeholder='Age'/>

<span className="block text-sm font-medium text-slate-700 mt-6">Profile picture</span>


<input type="file" className="px-4 py-2 border rounded-md w-full" placeholder='Profile
picture' />

<div className='mt-8'>
<button className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold
text-gray-700 mr-2 mb-2">Save</button>
</div>
</form>
</div>
</div>
)
}

export default Welcome

Guardamos los cambios

Abrimos el componente Profile.jsx y realizamos lo siguiente

1. Recibir la propiedad name en el componente <Profile />

const Profile = ({ image, name })

1. Cambiar el texto “Mi primer componente de React” por {name}

<p className="font-bold text-xl mb-2">{name}</p>

Lines en color morado

import React from 'react'

const Profile = ({ image, name }) => {

return (
<div className="max-w-sm rounded-md shadow-lg">
<img className="w-full h-72" src={image} alt="profile" />

<div className="px-6 py-4">


<p className="font-bold text-xl mb-2">{name}</p>
<p className="text-gray-700 text-base">
Shoulder drumstick leberkas velit ad ground round. Jowl voluptate pork chop ham hock veniam
reprehenderit pork loin minim.
</p>
</div>

<div className="px-6 pt-4 pb-2">


<button className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-
gray-700 mr-2 mb-2">Compartir</button>
</div>
</div>
)
}

export default Profile

Guardamos y observamos los cambios

CUARTO RETO:

1. Cambiar el campo Lastname por un campo de descripción (description)

2. Al momento de escribir en el campo de descripción debe verse reflejado en el cuerpo de la


tarjeta exactamente donde dice: “Shoulder drumstick leberkas…”

Actualizamos el acivo Welcome.jsx.

Se debe crear un estado para almacenar la descripción ingresada

const [description, setDescription] = useState('');

Maneja el cambio en el campo de texto para la descripción

const handleChangeDescription = (event) => {


setDescription(event.target.value);

Quedaria así

const Welcome = () => {

const [name, setName] = useState('');

const [description, setDescription] = useState('');

const handleChange = (event) => {

setName(event.target.value);

};

const handleChangeParagraph = (event) => {

setDescription(event.target.value);

};

Ahora se adiciona en el componente profile la descripción ingresada

<Profile image="https://cdn.pixabay.com/photo/2023/01/19/10/24/castle-7728772_1280.jpg"
name={name} description={description} />

Se modifica el campo de entrada para la descripción

<span className="block text-sm font-medium text-slate-700 mt-6">Description</span>

<input type="text" className="px-4 py-2 border rounded-md w-full"


placeholder='Description' value={description} onChange={handleChangeParagraph} />

Asi quedaría actualizado el archivo

import React, { useState } from 'react'

import Profile from '../components/Profile'

const Welcome = () => {

const [name, setName] = useState('');

const [description, setDescription] = useState('');

const handleChange = (event) => {


setName(event.target.value);

};

const handleChangeParagraph = (event) => {

setDescription(event.target.value);

};

return (

<div className="flex justify-center mt-6">

<div className='w-1/3'>

<Profile image="https://cdn.pixabay.com/photo/2023/01/19/10/24/castle-7728772_1280.jpg"
name={name} description={description} />

</div>

<div className='w-1/3'>

<form className='px-8 py-4 border rounded-md'>

<span className="block text-sm font-medium text-slate-700">Name</span>

<input type="text" className="px-4 py-2 border rounded-md w-full"


placeholder='Name' onChange={handleChange}/>

<span className="block text-sm font-medium text-slate-700 mt-6">Description</span>

<input type="text" className="px-4 py-2 border rounded-md w-full"


placeholder='Description' value={description} onChange={handleChangeParagraph} />

<span className="block text-sm font-medium text-slate-700 mt-6">Age</span>

<input type="range" className="px-4 py-2 border rounded-md w-full"


placeholder='Age'/>

<span className="block text-sm font-medium text-slate-700 mt-6">Profile


picture</span>

<input type="file" className="px-4 py-2 border rounded-md w-full"


placeholder='Profile picture' />

<div className='mt-8'>

<button className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-


semibold text-gray-700 mr-2 mb-2">Enviar</button>

</div>

</form>
</div>

</div>

export default Welcome

El siguiente paso es actualizar el archivo Profile.jsx

Se debe recibir la propiedad description

const Profile = ({ image, name, description }) => {

2. Cambiar el texto “Mi primer componente de React” por {description}

<p className="text-gray-700 text-base">{description}</p>

import React from 'react'

const Profile = ({ image, name, description }) => {

return (

<div className="max-w-sm rounded-md shadow-lg">

<img className="w-full" src={image} alt="profile" onMouseEnter={()=> alert("Imagen


ilustrada")}/>

<div className="px-6 py-4">

<p className="font-bold text-xl mb-2">{name}</p>

<p className="text-gray-700 text-base">{description}</p>

</div>

<div className="px-6 pt-4 pb-2">

<button className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold


text-gray-700 mr-2 mb-2">Compartir</button>

</div>

</div>

}
export default Profile;

Guardamos, actualizamos el navegador para verificar el correcto funcionamiento.

CONTINUAMOS AVANZANDO EN EL CUARTO RETO

4. La imagen debe ser dinámica para que se pueda subir una foto desde el computador y verse
reflejada en la tarjeta.

La dinamiza es igual a como la hemos venido trabajando para modificar los campos anteriores,
debemos realizar el siguiente procedimiento:

En el archivo Welcome.jsx

1. Añadir un estado para la imagen.

const [image, setImage] = useState('');

2. Actualizar el estado de la imagen cuando se selecciona un archivo.

const handleImageChange = (event) => {

const file = event.target.files[0];

if (file) {

const reader = new FileReader();

reader.onloadend = () => {

setImage(reader.result); // Actualiza el estado con la URL de datos de la imagen

};

reader.readAsDataURL(file);

};
3. Pasar la URL de la imagen al componente Profile.

<div className='w-1/3'>

<Profile image={image || "https://cdn.pixabay.com/photo/2023/01/19/10/24/castle-


7728772_1280.jpg"} name={name} description={description} />

</div>

El archivo actualizado quedaría así

import React, { useState } from 'react';

import Profile from '../components/Profile';

const Welcome = () => {

const [name, setName] = useState('');

const [description, setDescription] = useState('');

const [image, setImage] = useState('');

const handleChange = (event) => {

setName(event.target.value);

};

const handleChangeParagraph = (event) => {

setDescription(event.target.value);

};

const handleImageChange = (event) => {

const file = event.target.files[0];

if (file) {

const reader = new FileReader();

reader.onloadend = () => {

setImage(reader.result); // Actualiza el estado con la URL de datos de la imagen

};

reader.readAsDataURL(file);
}

};

return (

<div className="flex justify-center mt-6">

<div className='w-1/3'>

<Profile image={image || "https://cdn.pixabay.com/photo/2023/01/19/10/24/castle-


7728772_1280.jpg"} name={name} description={description} />

</div>

<div className='w-1/3'>

<form className='px-8 py-4 border rounded-md'>

<span className="block text-sm font-medium text-slate-700">Name</span>

<input type="text" className="px-4 py-2 border rounded-md w-full"


placeholder='Name' onChange={handleChange}

/>

<span className="block text-sm font-medium text-slate-700 mt-6">Description</span>

<input type="text" className="px-4 py-2 border rounded-md w-full"


placeholder='Description' value={description} onChange={handleChangeParagraph} />

<span className="block text-sm font-medium text-slate-700 mt-6">Age</span>

<input type="range" className="px-4 py-2 border rounded-md w-full"


placeholder='Age' />

<span className="block text-sm font-medium text-slate-700 mt-6">Profile


picture</span>

<input type="file" className="px-4 py-2 border rounded-md w-full"


onChange={handleImageChange} />

<div className='mt-8'>

<button className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-


semibold text-gray-700 mr-2 mb-2">

Compartir

</button>

</div>

</form>
</div>

</div>

);

};

export default Welcome;

El archivo Profile ya tiene el parámetro

Profile.jsx

import React from 'react'

const Profile = ({ image, name, description }) => {

return (

<div className="max-w-sm rounded-md shadow-lg">

<img className="w-full" src={image} alt="profile" onMouseEnter={()=> alert("Imagen


ilustrada")}/>

<div className="px-6 py-4">

<p className="font-bold text-xl mb-2">{name}</p>

<p className="text-gray-700 text-base">{description}</p>

</div>

<div className="px-6 pt-4 pb-2">

<button className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-


semibold text-gray-700 mr-2 mb-2">Compartir</button>

</div>

</div>

export default Profile;

CONTINUAMOS AVANZANDO EN EL CUARTO RETO


4. Los inputs se repiten con las mismas clases y se repite mucho código, crear componentes
para reutilizar código.

La creación de componentes reutilizables para los diferentes tipos de inputs, permite evitar la
repetición de código y mantener tus componentes más limpios.

CREACIÓN DE LOS ARCHIVOS DE LOS COMPONENTES

1. Crear el archivo TextInput.js

// src/components/TextInput.js

import React from 'react';

const TextInput = ({ label, placeholder, value, onChange }) => (

<div className="mb-6">

<label className="block text-sm font-medium text-slate-700">{label}</label>

<input

type="text" className="px-4 py-2 border rounded-md w-full" placeholder={placeholder}


value={value} onChange={onChange} />

</div>

);

export default TextInput;

2. Crear el archivo FileInput.js

// src/components/FileInput.js

import React from 'react';

const FileInput = ({ label, onChange }) => (

<div className="mb-6">

<label className="block text-sm font-medium text-slate-700">{label}</label>

<input type="file" className="px-4 py-2 border rounded-md w-full" onChange={onChange} />

</div>
);

export default FileInput;

3. Crear el archivo RangeInput.js

// src/components/RangeInput.js

import React from 'react';

const RangeInput = ({ label }) => (

<div className="mb-6">

<label className="block text-sm font-medium text-slate-700">{label}</label>

<input type="range" className="px-4 py-2 border rounded-md w-full"

/>

</div>

);

export default RangeInput;

ACTUALIZAR EL COMPONENTE Welcome.jsx

Para refactorizar el componente welcome usamos los nuevos componentes en la pagina


Welcome.jsx

Lo primero es importar los componentes

import TextInput from '../components/TextInput';

import FileInput from '../components/FileInput';

import RangeInput from '../components/RangeInput';

Modificamos cada uno de los elementos de los formularios teniendo en cuenta los componentes.
<form className='px-8 py-4 border rounded-md'>

<TextInput label="Name" placeholder="Name" value={name} onChange={handleChangeName}


/>

<TextInput label="Description" placeholder="Description" value={description}


onChange={handleChangeDescription} />

<RangeInput label="Age" />

<FileInput label="Profile picture" onChange={handleImageChange} />

Finalmente quedaría así

import React, { useState } from 'react';

import Profile from '../components/Profile';

import TextInput from '../components/TextInput';

import FileInput from '../components/FileInput';

import RangeInput from '../components/RangeInput';

const Welcome = () => {

const [name, setName] = useState('');

const [description, setDescription] = useState('');

const [image, setImage] = useState('');

const handleChangeName = (event) => {

setName(event.target.value);

};

const handleChangeDescription = (event) => {

setDescription(event.target.value);

};

const handleImageChange = (event) => {

const file = event.target.files[0];

if (file) {
const reader = new FileReader();

reader.onloadend = () => {

setImage(reader.result);

};

reader.readAsDataURL(file);

};

return (

<div className="flex justify-center mt-6">

<div className='w-1/3'>

<Profile image={image || "https://cdn.pixabay.com/photo/2023/01/19/10/24/castle-


7728772_1280.jpg"} name={name} description={description} />

</div>

<div className='w-1/3'>

<form className='px-8 py-4 border rounded-md'>

<TextInput label="Name" placeholder="Name" value={name} onChange={handleChangeName}


/>

<TextInput label="Description" placeholder="Description" value={description}


onChange={handleChangeDescription} />

<RangeInput label="Age" />

<FileInput label="Profile picture" onChange={handleImageChange} />

<div className='mt-8'>

<button className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-


semibold text-gray-700 mr-2 mb-2">

Enviar

</button>

</div>

</form>

</div>
</div>

);

};

export default Welcome;

En conclusión se han creado componentes TextInput, FileInput y RangeInput para manejar los
diferentes tipos de inputs. Estos componentes encapsulan la lógica y el estilo de los inputs,
haciendo que el código sea más limpio y fácil de mantener.

Uso en Welcome: En lugar de repetir el código para cada tipo de input, ahora se utilizan los
componentes reutilizables. Esto simplifica el componente Welcome y mejora su legibilidad.

Con esta estructura, se pueden agregar fácilmente nuevos tipos de inputs o modificar los
existentes sin tener que cambiar el código en varios lugares. Además, si en el futuro se requiere
cambiar el estilo o el comportamiento de los inputs, solo tendremos que hacerlo en un solo
lugar.

CONTINUAMOS AVANZANDO EN EL CUARTO RETO

4. Crear la funcionalidad que desee con el botón “Save” y el evento onSubmit de JavaScript.

Para agregar la funcionalidad al botón "Save" utilizando el evento onSubmit, se requiere hacer
algunos ajustes en el componente Welcome y en el formulario.

Sugerencias:

Actualizar el botón a tipo submit (Puedes seguir los siguientes pasos para realizar el reto)

1. Cambia el botón dentro del formulario para que sea un botón de tipo submit en lugar de un
botón estándar.
2. Agregar el controlador de eventos onSubmit. Añade un controlador de eventos onSubmit al
formulario para manejar el envío de datos.
3. Funcionalidades Adicionales. Si deseas agregar funcionalidades adicionales, como mostrar un
mensaje de éxito o error después del envío, o resetear el formulario, puedes hacerlo dentro del
manejador handleSubmit.

¡ÉXITOS!

También podría gustarte