Este blog tiene como finalidad de compartir conocimientos y aportar un granito más de información. Comparto mis apuntes e información que he encontrado por Internet, teniendo en cuenta que muchas ideas escritas no son propias, en la parte inferior coloco la url de los sitios donde esta la idea original ... espero que les sea de utilidad.
Creando nuestro primer " Hola mundo ! "
Para comenzar crearemos nuestra aplicacion con los comandos
npx create-react-app inicio
entramos a la carpeta del proyecto
cd inicio
lo ejecutamos
npm start
lo visualizamos en el navegador
posteriormente paramos el servicio con la combinacion de teclas Ctrl + C.
Comenzamos atrabaja abriendo nuestro proyecto con el editor Visual Studio Code posteriomente eliminaremos la carpeta src click derecho eliminar.
Crearemos de nuevo la carpeta src, esto lo realizamos para comenzar desde cero, con clic derecho -> nuevo archivo o clic en el icono nuevo archivo
Posteriormente vamos a crearemos el archivo index.js par tener nuestro punto de partida
y colocamos este codigo en el archivo index.js
//importamos el paquete de react , esta dependencia
// la podemos localizar en el archivo package.json
import React from"react";
//importamos el paquete de react-dom para
//poder manipular el DOM de la pagina
import ReactDOM from"react-dom/client";
// creamos y seleccionamos un nuevo contenedor de raíz en
//la página web utilizando el elemento con el ID 'root'.
// utilizamos el método render del contenedor root para
//devolver el contenido que será representado en el navegador.
root.render(<h1>hola mundo</h1>)
Es importante destacar que el método render debe ser puro y no debe realizar ninguna operación que modifique el estado del componente ni interactúe con el navegador directamente. Su única responsabilidad es devolver una representación del componente en función de su estado y sus propiedades actuales.
continuemos con los siguientes conceptos muy importantes en react componente y modulo que son las unidades basicas de la interfaz de usuario (UI) ,el componente puede ser dividiendose en componentes de clase y componentes de funcion para encapsulan la lógica y la presentación, mientras que los módulos en React se utilizan para organizar y modularizar el código de la aplicación, agrupando funcionalidades relacionadas en archivos individuales. veamos cada uno en particular.
Módulo en React
Un módulo en React se refiere a un archivo de JavaScript que encapsula la funcionalidad relacionada. En React, los módulos se utilizan para organizar el código en componentes individuales, utilidades, estilos y otras partes de la aplicación. Cada componente de React suele estar definido en su propio módulo, lo que facilita la organización y la reutilización del código.
Componente en React
Un componente en React es una pieza reutilizable de la interfaz de usuario que encapsula la lógica y la presentación de una parte específica de la interfaz de usuario. Los componentes pueden ser simples o complejos, y pueden contener otros componentes, lo que permite construir interfaces de usuario jerárquicas y modulares.
Vamos a crear nuestro modulo saludo (saludo.js) con el componente Saludo, tome en cuenta que el nombre del modulo se escribe con minusculas y el nombre del componente siempre la primera letra es mayuscula asi podemos diferenciar el componente con el modulo.
Creamos el archivo saludo.js
Escribimos el siguiente codigo
exportfunction Saludo(){
return (<h1>hola mundo </h1>);
}
explicacion simple
export: La palabra clave export se utiliza para exportar una función, clase, variable o constante para que esté disponible para ser importada por otros módulos.
function Saludo() { ... }: Esto define una función llamada Saludo. La función no toma ningún argumento y devuelve un elemento JSX. En este caso, el elemento JSX es un encabezado (<h1>) que contiene el texto "¡Hola mundo!".
return <h1>¡Hola mundo!</h1>;: Esta es la declaración de retorno de la función. Devuelve el elemento JSX que representa un encabezado de nivel 1 con el texto "¡Hola mundo!".
Este código exporta una función llamada Saludo que devuelve un elemento JSX que representa un encabezado con el texto "¡Hola mundo!". Cuando importas este módulo en otro archivo JavaScript, puedes utilizar la función Saludo para renderizar este elemento JSX en tu aplicación React.
En el archivo index.js escribimos el siguiente codigo
En este ejemplo, Saludo se importa desde el modulo donde está definido (./saludo) y se utiliza dentro del contenedor ( root ) para renderizar el mensaje "¡Hola mundo!" , dentro del contenedor se invoca el elemento Saludo en la interfaz de usuario.
Formas de invocar al componente
En el ejemplo anterior se hace el llamado al elemeto Saludo y un comentario, veamos a continuacion la forma de colocar un comentario y llamar al elemento.
root.render(
//Utilizamos varios componente Saludo
<>
{/*Utilizamos nuestro comonente Saludo*/}
<Saludo/>
<Saludo></Saludo>
{Saludo()}
</>
)
Explicacion simple
La sintaxis <></> en React se conoce como un fragmento o fragmento vacío.Es una característica introducida en React para permitir la agrupación de múltiples elementos JSX sin agregar un nodo adicional al DOM resultante. Esto es útil cuando deseas devolver múltiples elementos JSX en una función o componente de React sin tener que envolverlos en un elemento contenedor adicional.
Los comentarios en línea en React se escriben entre llaves {} y barras diagonales /* */, de manera similar a los comentarios en JavaScript estándar. Dentro de estos caracteres, puedes escribir cualquier texto que desees, y se interpretará como un comentario y no se renderizará en el DOM final.
<Saludo/>: Esta sintaxis se utiliza para renderizar un componente de React. Cuando utilizas <Saludo/>, estás creando una instancia del componente Saludo y React se encarga de renderizar su salida en el DOM. Este es el enfoque típico para renderizar componentes en React y es útil cuando deseas renderizar un componente que está definido como una clase o una función de React.
<Saludo></Saludo>: Esta forma es equivalente a la primera, pero utiliza la sintaxis de etiqueta de apertura y cierre para el componente Saludo. Aunque esta forma es menos común, funciona de la misma manera que la primera y también crea una instancia del componente Saludo y lo renderiza en el árbol DOM.
{Saludo()}: Esta sintaxis se utiliza para llamar a una función de JavaScript y renderizar el valor que devuelve. En este caso, Saludo parece ser una función que devuelve un elemento JSX. Cuando utilizas {Saludo()}, estás llamando a la función Saludo y el elemento JSX que devuelve se renderiza en el DOM. Este enfoque es útil cuando deseas renderizar dinámicamente contenido basado en lógica o datos de tu aplicación.
Continuando con el ejemplo anterior ,si tienes duda del comentario cuando ocupar // o {/**/} esto coresponde si esta en un componente o no.
root.render(
//comentario a fuera del componente
<>
{/*comentario dentro de un componente*/}
{/*Utilizamos nuestro comonente Saludo*/}
<Saludo/>
{Saludo()}
</>
)
Relacion entre componentes
En React, la relación entre componentes se puede describir en términos de componentes padres e hijos. Estos términos se utilizan para describir cómo los componentes se relacionan entre sí en una jerarquía de componentes. Aquí tienes una explicación más detallada:
Componente Padre
Un componente padre en React es aquel que contiene y engloba a otro componente dentro de su estructura. Este componente es responsable de renderizar y controlar el componente hijo, así como de pasarle datos y propiedades si es necesario. En términos de jerarquía, un componente padre puede tener varios componentes hijos anidados dentro de él.
Componente Hijo
Un componente hijo en React es aquel que está contenido dentro de otro componente (el componente padre). Este componente hijo puede recibir datos y propiedades del componente padre a través de sus props, pero no tiene conocimiento directo del estado o las propiedades de otros componentes fuera de su ámbito.
Relación entre Componente Padre e Hijo
La relación entre un componente padre y sus hijos es una de composición. Esto significa que un componente padre compone o ensambla varios componentes hijos para formar una interfaz de usuario más grande y compleja. Los componentes hijos pueden ser reutilizables y pueden ser compartidos entre varios componentes padres.
Con esto se puede decir que en React, un componente padre es aquel que contiene y engloba a otro componente (el componente hijo) dentro de su estructura. El componente padre es responsable de renderizar y controlar el componente hijo, y puede pasarle datos y propiedades según sea necesario. La relación entre componentes padres e hijos es una relación de composición, donde los componentes padres ensamblan y componen varios componentes hijos para formar una interfaz de usuario más grande y compleja.
//contenedor root
root.render(
//componente padre
<>
{/*componente hijo*/}
<Saludo/>
{/*componente hijo*/}
<Saludo></Saludo>
{/*llamado a funcion que renderiza un componente hijo*/}
{Saludo()}
</>
)
Manejo de valores y variables
Para entender el manejo de una variable promero hay que entender que es alcance de bloque de una variable y posteriormente podemos ver como se maneja el valor de esa variable.
Alcance de bloque de una variable
El alcance de bloque de una variable se refiere a la visibilidad y disponibilidad de esa variable dentro de un bloque de código específico. En React, al igual que en JavaScript en general, el alcance de bloque se aplica a las variables declaradas con let y const, ya que estas variables tienen un alcance limitado al bloque de código en el que fueron declaradas, mientras que var tinene alcance de función.
El alcance de bloque es útil para evitar la contaminación del ámbito global y para asegurar que las variables sean utilizadas solo donde se necesitan. También facilita la depuración y el mantenimiento del código al hacer que el flujo de datos sea más predecible y controlado.
Evitar usar variables declaradas con VAR por las siguientes razones.
Alcance de bloque:
Las variables declaradas con var tienen un alcance de función, lo que significa que su ámbito está limitado al bloque de la función más cercana en la que fueron declaradas. Esto puede conducir a problemas de alcance y errores inesperados, especialmente cuando se utilizan en bloques de código como bucles for o condicionales if.
Hoisting (Elevación):
Las variables declaradas con var son elevadas (hoisted) al principio de su ámbito de función, lo que significa que pueden ser accesibles incluso antes de que se declaren. Esto puede conducir a comportamientos inesperados y dificultades para entender el código.
Reasignación involuntaria:
Debido a su alcance menos estricto, las variables declaradas con var pueden ser reasignadas inadvertidamente en diferentes partes del código, lo que puede hacer que sea más difícil rastrear y depurar problemas.
Compatibilidad con ECMAScript 6 (ES6):
Con la introducción de let y const en ES6, se proporcionaron alternativas más seguras y predecibles para declarar variables. let tiene un alcance de bloque y puede ser reasignado, mientras que const también tiene un alcance de bloque pero no puede ser reasignado después de su declaración.
Por estas razones es preferible utilizar let o const, que tienen un alcance de bloque más estricto y son más seguros.
Declarar variables
let
let es una forma moderna de declarar variables que se introdujo en ES6. Tiene un alcance de bloque, lo que significa que su ámbito está limitado al bloque de código en el que se declaró. Esto evita los problemas asociados con var y es más seguro de usar en general.
let y = 20;
const
const es otra forma de declarar variables que se introdujo en ES6. Se utiliza para declarar variables cuyos valores no cambiarán a lo largo del tiempo. Al igual que let, tiene un alcance de bloque y no puede ser reasignada después de su declaración.
const z = 30;
Es importante destacar que const no hace que el valor de la variable sea inmutable, sino que hace que la referencia a la variable sea inmutable. Esto significa que no puedes reasignar la variable a otro valor, pero sí puedes modificar las propiedades de un objeto o un arreglo si la variable es un objeto o un arreglo.
Además de estas dos formas principales, también puedes declarar variables utilizando destructuración, importación de módulos, y más. Pero let y const son las formas estándar y más comunes de declarar variables.
Tipos de datos
En React, al igual que en JavaScript en general, puedes trabajar con varios tipos de valores que se utilizan para diferentes propósitos en tus componentes y aplicaciones. Aquí tienes una lista de los tipos de valores más comunes que encontrarás al trabajar con React:
Strings (Cadenas de texto):Los strings son secuencias de caracteres que representan texto. Se utilizan ampliamente para mostrar contenido textual en la interfaz de usuario.
Numbers (Números):Los números son valores numéricos, ya sea enteros o de punto flotante. Se utilizan para representar cantidades, medidas, índices, etc.
Booleans (Booleanos):Los booleanos son valores que pueden ser true o false. Se utilizan para representar condiciones lógicas, como activar o desactivar una funcionalidad.
Arrays (Arreglos):Los arrays son estructuras de datos que contienen una colección ordenada de elementos, los cuales pueden ser de cualquier tipo de dato, incluyendo otros arrays. Son útiles para manejar colecciones de datos y repetir elementos en la interfaz de usuario.
Objects (Objetos):Los objetos son estructuras de datos que contienen pares clave-valor. Cada clave es un string que identifica un valor asociado. Los objetos se utilizan para representar estructuras más complejas de datos y para organizar información relacionada.
Functions (Funciones):Las funciones son bloques de código que se pueden ejecutar para realizar una tarea específica. Se utilizan para encapsular la lógica y el comportamiento en tu aplicación.
React Elements (Elementos de React):Los elementos de React son objetos que representan componentes en la interfaz de usuario. Se crean utilizando JSX y se utilizan para renderizar la interfaz de usuario en el DOM.
Props (Propiedades):Las propiedades son valores que se pasan de un componente padre a un componente hijo. Se utilizan para personalizar y configurar los componentes en React.
State (Estado):El estado es un objeto que contiene datos que pueden cambiar a lo largo del tiempo. Se utiliza para mantener y gestionar el estado de un componente en React.
Undefined (Indefinido) y Null:Estos son valores especiales que representan la ausencia de valor. Undefined se utiliza cuando una variable no está definida, mientras que null se utiliza para indicar la ausencia intencionada de un valor.
Estos son algunos de los tipos de valores más comunes que encontrarás . Es importante comprender estos tipos de valores y cómo se utilizan en tu código para construir aplicaciones efectivas y funcionales.
uso de jsx
JSX (JavaScript XML) es una extensión de la sintaxis de JavaScript que te permite escribir código HTML dentro de JavaScript de una manera más intuitiva y expresiva. JSX es una característica fundamental de React y se utiliza para definir la estructura de la interfaz de usuario en las aplicaciones React.
Comillas Simples ('), Comillas Dobles (") y Backticks (`)
En React, así como en JavaScript en general, las comillas simples ('), las comillas dobles (") y los backticks (`) son utilizados para definir cadenas de texto. Cada uno de estos tipos de comillas tiene sus propias características y se utiliza en diferentes situaciones:
Comillas Simples (') y Comillas Dobles ("):
Ambas se utilizan para definir cadenas de texto de forma similar.
Se pueden usar indistintamente para definir cadenas de texto simples.
Backticks (`):
Introducidos en ECMAScript 6 (ES6), los backticks se utilizan para crear plantillas de cadenas o "template strings".
Permiten la interpolación de expresiones utilizando ${} dentro de la cadena.
También permiten el uso de expresiones de múltiples líneas sin necesidad de concatenación o caracteres de escape.
El operador &&
El operador && en JavaScript se utiliza para evaluar dos expresiones lógicas. En el contexto de React (y JavaScript en general), el operador && se utiliza a menudo para condicionar la renderización de componentes o para hacer que ciertas partes de una expresión se evalúen solo si se cumple una condición.
Cuando se usa en una expresión A && B, el operador && evalúa A primero. Si A es evaluado como verdadero, entonces se evalúa B y el resultado de la expresión es el valor de B. Si A es evaluado como falso, la evaluación de B se omite y el resultado de la expresión es el valor de A.
En React, puedes usar el operador && dentro del JSX para condicionar la renderización de un componente o de parte de un componente. Aquí hay un ejemplo:
function EjemploComponente({ mostrarMensaje }) {
return (
<div>
{/* Renderiza el mensaje solo si mostrarMensaje es verdadero */}
{mostrarMensaje && <p>¡Este es un mensaje importante!</p>}
</div>
);
}
En este ejemplo, el componente EjemploComponente solo renderizará el <p> si la prop mostrarMensaje es verdadera. Si mostrarMensaje es falsa, el <p> no se renderizará en el DOM.
El uso del operador && de esta manera es una forma concisa de condicionar la renderización de elementos en React y se utiliza comúnmente para mostrar o ocultar componentes basados en el estado o las propiedades de un componente.
El operador ||
El operador || en JavaScript se conoce como el operador "o lógico" (OR en inglés). En React, al igual que en JavaScript en general, se utiliza para evaluar dos expresiones lógicas y devuelve true si al menos una de las expresiones es verdadera, y false si ambas son falsas.
Cuando se usa en una expresión A || B, el operador || evalúa A primero. Si A es evaluado como verdadero, entonces no se evalúa B y el resultado de la expresión es el valor de A. Si A es evaluado como falso, se evalúa B y el resultado de la expresión es el valor de B.
En el contexto de React, el operador || se puede utilizar para proporcionar un valor predeterminado o alternativo a una expresión. Por ejemplo:
En este ejemplo, si nombreUsuario es una cadena de texto válida, entonces nombreMostrado será igual a nombreUsuario. Si nombreUsuario es falsa (por ejemplo, si es null, undefined o una cadena vacía), entonces nombreMostrado será igual a 'Invitado'. Esto permite proporcionar un valor predeterminado en caso de que nombreUsuario no esté definido.
El operador || se utiliza comúnmente en React para establecer valores predeterminados, especialmente cuando se trabaja con propiedades que pueden ser null o undefined. Sin embargo, es importante tener en cuenta que el operador || devolverá el primer valor que se evalúe como verdadero, lo que puede no ser lo que se espera en todas las situaciones. Por lo tanto, es importante comprender bien cómo funciona este operador y utilizarlo con precaución.
Argumento rest
El "argumento rest" en React, al igual que en JavaScript en general, se refiere al operador de rest (...) que se utiliza para recoger los argumentos restantes en una función. Este operador permite trabajar con un número variable de argumentos en una función y los recoge en un solo objeto iterable, generalmente llamado rest o cualquier otro nombre descriptivo.
En el contexto de React, el argumento rest se usa comúnmente en componentes funcionales para recoger todas las propiedades pasadas al componente y agruparlas en un solo objeto. Esto es particularmente útil cuando se trabaja con props que pueden variar en número o cuando se desea reenviar un conjunto completo de props a otro componente.
// prop1 y prop2 son propiedades específicas del componente
// El operador rest recoge todas las demás propiedades en el objeto "rest"
// Hacer algo con prop1 y prop2
return (
<div>
<p>Propiedad 1: {prop1}</p>
<p>Propiedad 2: {prop2}</p>
{/* Reenviar todas las otras props a otro componente */}
<OtroComponente{...rest}/>
</div>
);
};
exportdefault MiComponente;
El operador spread (...)
Es una característica de JavaScript que se utiliza para expandir elementos en un lugar donde se esperan múltiples elementos. En el contexto de React, el operador spread se utiliza comúnmente para trabajar con arrays y objetos, permitiendo la copia o la combinación de elementos de una manera concisa y expresiva.
Aquí hay algunos ejemplos de cómo se utiliza el operador spread en JavaScript y en React:
Con Arrays:
Copia de arrays:
const array1 = [1, 2, 3];
const array2 = [...array1]; // Copia array1 en array2
Combinación de arrays:
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const array3 = [...array1, ...array2]; // Combina array1 y array2 en array3
const objeto3 = { ...objeto1, ...objeto2 }; // Combina objeto1 y objeto2 en objeto3
En el contexto de React, el operador spread es particularmente útil para trabajar con props en componentes funcionales. Por ejemplo, al crear un nuevo objeto de props, se pueden combinar las props existentes con nuevas props utilizando el operador spread:
El operador spread (...) es una característica poderosa de JavaScript que se utiliza para copiar, combinar o expandir arrays y objetos en contextos donde se esperan múltiples elementos, como en React al trabajar con props de componentes.
Funcion autoinvocada
Una función anidada autoinvocada, también conocida como IIFE (Immediately Invoked Function Expression) en inglés, es una función definida y ejecutada inmediatamente después de su declaración. Este patrón es comúnmente utilizado en JavaScript para encapsular variables y lógica dentro de un ámbito local, evitando así que las variables definidas en la función afecten el ámbito global.
Una función anidada autoinvocada se ve así:
(function() {
// Código de la función
})();
En este patrón:
Se define una función anónima dentro de paréntesis.
Inmediatamente después de la definición de la función, se colocan otros paréntesis () para invocarla.
Esto hace que la función se ejecute inmediatamente después de su definición.
Este patrón es útil para encapsular código y evitar conflictos de nombres en el ámbito global. También se utiliza a menudo para crear módulos en JavaScript, ya que permite definir variables y funciones que son locales al ámbito de la IIFE y no interfieren con otras partes del código.
Aquí hay un ejemplo de cómo se utiliza una IIFE para encapsular código:
(function() {
var nombre = 'Juan';
console.log('Hola, ' + nombre);
})();
El operador ?
El operador de encadenamiento opcional o "Optional Chaining" en inglés. Este operador se utiliza en JavaScript (y por ende en React) para acceder a propiedades de objetos que pueden no estar definidas o pueden ser null o undefined, evitando así errores de referencia no definida (como TypeError: Cannot read property 'propiedad' of undefined).
objeto.propiedad?.subpropiedad
Este operador permite acceder a la subpropiedad subpropiedad del objeto objeto.propiedad solo si objeto.propiedad no es null o undefined. Si objeto.propiedad es null o undefined, la expresión completa se evaluará como undefined.
En el contexto de React, el operador de encadenamiento opcional es particularmente útil al trabajar con props de componentes, especialmente cuando las props pueden no estar definidas. Por ejemplo:
const MiComponente = ({ datos }) => {
return (
<div>
{datos?.nombre}{/* Accede a datos.nombre solo si datos no es null o undefined */}
</div>
);
};
En este ejemplo, si datos es null o undefined, la expresión {datos?.nombre} se evaluará como undefined y no se producirá un error al intentar acceder a la propiedad nombre. Esto ayuda a evitar errores en tiempo de ejecución y hace que el código sea más robusto.
Uso de { }
Las llaves { } se utilizan para incorporar expresiones JavaScript dentro de JSX (JavaScript XML). Esto te permite insertar valores dinámicos, realizar operaciones y ejecutar lógica JavaScript dentro de tus componentes de React.
Aquí hay algunos casos comunes de cómo se usan los corchetes {} en React:
Incorporar variables y expresiones
Puedes utilizar los corchetes {} para incrustar variables y expresiones JavaScript dentro de tu JSX. Por ejemplo:
El operador ternario ( condición ? expresión1 : expresión2) es ampliamente utilizado en React para realizar renderizado condicional. Puedes usarlo para renderizar diferentes componentes o elementos basados en una condición. Aquí tienes algunos ejemplos de cómo usar el operador ternario en React.
Este término describe la práctica de colocar un componente dentro de otro componente, creando así una estructura jerárquica de componentes en su aplicación.
const miComponente = () => { ... };: Se define un componente funcional llamado miComponente. Dentro de este componente, se define otra función llamada componenteInterno que devuelve un elemento JSX <p> este es un componente interno </p>. Luego, el componente externo miComponente devuelve el resultado de llamar a componenteInterno.
Usar modulos
Los módulos en React se utilizan para organizar y reutilizar la lógica de la aplicación, mientras que los elementos se utilizan para representar la interfaz de usuario y definir lo que se debe renderizar en la pantalla. Ambos son componentes clave en el desarrollo de aplicaciones.
La organización de los elementos dentro de los módulos en React es una práctica importante para mantener tu código limpio, legible y fácil de mantener. Aquí hay algunas pautas generales sobre cómo organizar tus elementos dentro de los módulos en React:
1. Dividir por Funcionalidad
Organiza tus elementos en módulos según la funcionalidad o la responsabilidad que tengan en tu aplicación. Por ejemplo, podrías tener un módulo para la barra de navegación, otro para los componentes relacionados con la autenticación, otro para la página de inicio, etc.
2. Crea Componentes Reutilizables
Identifica patrones de diseño repetitivos en tu aplicación y crea componentes reutilizables para manejarlos. Estos componentes pueden incluir botones, formularios, tarjetas, encabezados, pies de página, etc. Organice estos componentes en un directorio separado para facilitar su reutilización en toda su aplicación.
3. Utiliza Carpetas y Archivos
Organiza tus elementos en una estructura de carpetas y archivos lógica y fácil de entender. Puedes agrupar componentes relacionados en carpetas y dividirlos en archivos individuales según sea necesario. Por ejemplo:
4. Mantén un estilo consistente
Sigue un estilo de nomenclatura consistente para los nombres de los archivos y los componentes. Esto facilita la búsqueda y comprensión del código. Por ejemplo, podría utilizar el PascalCase para los nombres de los componentes y el camelCase para los nombres de los archivos.
5. Separación de Responsabilidades
Asegúrese de que cada componente o módulo tenga una sola responsabilidad y haga una sola cosa. Esto facilita la reutilización, el testing y el mantenimiento del código.
6. Comentarios y Documentación
Incluye comentarios descriptivos en tu código para explicar el propósito y el funcionamiento de cada componente o módulo. Esto ayuda a otros desarrolladores (ya ti mismo en el futuro) a entender rápidamente el código ya realizar cambios de manera segura.
Siguiendo estas prácticas de organización, puedes mantener tu código React bien estructurado, modular y fácil de mantener a medida que tu aplicación crece y evoluciona.
Documentación de un componente
Para documentar un componente de React, puedes agregar comentarios directamente en el código fuente de ese componente. Estos comentarios proporcionan información sobre cómo se debe utilizar el componente, qué accesorios se aceptan y cualquier otra información relevante que pueda ser útil para otros desarrolladores que utilicen ese componente.
ejemplo de documentación de un componente
import React from'react';
import PropTypes from'prop-types';
// Esta es la documentacion de un componente
/**
* Nombre de elemeto.
*
* @paramNo tiene parametros.
*/
const MiComponente= () =>{
const componenteInterno = () => {
return (<p>este es un mensaje del componente interno</p>);
}
return (componenteInterno());
};
//Validación de parametros
MiComponente.propTypes = {
//sin restriciones de parametros
};
exportdefault MiComponente;
Explicacion simple
Descripcion de parametros
@param: Describe los parámetros que recibe la función. En este caso, describa los accesorios del componente Button.
@returns: Describe lo que devuelve la función. En este caso, describe el JSX que se renderiza.
@type: Describa el tipo de parámetro, si es necesario.
@defaultValue: Describa el valor por defecto de un parámetro, si es opcional.
Definir el tipo de restricciónes para los datos esperados para cada parametro (instala npm install --save prop-types para poder utlizar PropTypes)
PropTypes.string: Valida que la prop sea una cadena.
PropTypes.number: Valida que la prop sea un número.
PropTypes.bool: Valida que la prop sea un booleano.
PropTypes.func: Valida que la prop sea una función.
PropTypes.array: Valida que la prop sea un array.
PropTypes es una biblioteca utilizada en React para validar las propiedades (props) que recibe un componente. Permite definir el tipo de datos esperados para cada propiedad y, opcionalmente, si es obligatorio o tiene un valor predeterminado. Esto ayuda a identificar errores de tipo en tiempo de desarrollo ya documentar claramente cómo se deben usar los componentes.
Modulo documentado
Creamos el archivo "modulo" con la documentacion del componente que en seguida se indica
Codigo del archivo modulo.js
import React from'react';
import PropTypes from'prop-types';
// Esta es la documentacion de un elemento
/**
* Componente Suma.
*
* @paramX primer numero a sumar.
* @paramY segundo numero a sumar.
* @type Numericos
* @returns Regresa el resultado de la suma de dos numeros
* @defaultValue Valor por defecto de X=1 y el valor de Y=1
Para visualizar la documentacion del componente se coloca el puntero ensima del nombre del componente y para ir al componente preciona Ctrl + Click
En caso de recibir otro valor distinto de un numero en la validacion del parametro, el mensaje se vera de esta forma.
index.js:12 Advertencia: Tipo de propiedad fallida: propiedad no válida `x` de tipo `cadena` suministrada a `Suma`, `número` esperado.
Explicacion de Import
La instrucción import se utiliza para importar código desde otros archivos o módulos JavaScript dentro de tu aplicación. Esto es útil para reutilizar funciones, componentes, variables u otros elementos definidos en otros archivos en tu proyecto.
La sintaxis básica de importes la siguiente:
import nombre from 'ruta/al/archivo';
nombre: Es el nombre que le asignas al módulo que estás importando. Puedes usar cualquier nombre válido de JavaScript. Puede ser un nombre específico si estás importando una exportación nombrada o cualquier nombre si estás importando una exportación predeterminada.
'ruta/al/archivo': Es la ruta del archivo o módulo que estás importando. Puede ser una ruta relativa (comenzando con ./) o una ruta absoluta.
Importación de exportaciones nombradas
Puedes importar exportaciones nombradas utilizando la sintaxis de desestructuración
import { nombreExportacion } from 'ruta/al/archivo';
nombreExportacion :Es el nombre de la exportación que deseas importar del archivo o módulo especificado.
Importación de exportación predeterminada
Puedes importar la exportación predeterminada utilizando cualquier nombre que desees:
import nombre from 'ruta/al/archivo';
nombre: Es el nombre que asignas a la exportación predeterminada del archivo o módulo especificado.
Uso de alias
Puedes utilizar alias para renombrar las exportaciones que estás importando
import { nombre as alias } from 'ruta/al/archivo';
alias: Es el nombre que deseas asignar a la exportación que estás importando.
Importación de todo el módulo
También puedes importar todo un módulo en un solo objeto utilizando la sintaxis de asterisco ( *)
import * as modulo from 'ruta/al/archivo';
modulo: Es el objeto que contiene todas las exportaciones del archivo o módulo especificado.
Explicación de export
La instrucción export se utiliza para exportar funciones, variables, clases u otros elementos desde un archivo o módulo JavaScript para que puedan ser utilizados en otros archivos o módulos de tu aplicación. Esto es fundamental para modularizar y organizar tu código en componentes reutilizables y separados.
Puedes exportar cualquier elemento válido de JavaScript utilizando la palabra clave export seguida del elemento que deseas exportar. Aquí tienes algunos ejemplos:
Exportación de una función
export function myFunction() {
// Código de la función
}
Exportación de una variable:
export const myVariable = 10;
Exportación de una constante
const PI = 3.14;
export { PI };
Exportación de una clase
export class MyClass {
// Código de la clase
}
Exportación por defecto
Además de las exportaciones nombradas, también puedes exportar un solo elemento como predeterminado desde un archivo o módulo utilizando la palabra clave export default. Solo puede haber una exportación predeterminada por archivo.
Ejemplo de exportación predeterminada
const myVariable = 'Hola Mundo';
export default myVariable;
Cuando importas una exportación predeterminada en otro archivo, puedes asignarle cualquier nombre que desees durante la importación.
import nombrePersonalizado from './ruta/al/archivo';
Consideraciones adicionales
Puedes combinar exportaciones nombradas y exportación predeterminada en el mismo archivo, pero solo puede haber una exportación predeterminada.
Puedes importar elementos exportados en otros archivos utilizando la instrucción import
las exportaciones nombradas deben tener el mismo nombre durante la importación, las exportaciones pueden ser funciones, variables, constantes, clases o cualquier otro elemento de JavaScript válido.
Explicacion de props
Las props (abreviatura de propiedades) son un mecanismo fundamental para pasar datos de un componente a otro. Son simplemente objetos JavaScript.Un objeto de props en React contiene todas las propiedades que se pasan del componente padre a un componente hijo. Estas propiedades pueden ser de cualquier tipo, incluyendo números, cadenas, objetos, funciones, etc.
El objeto props es un objeto JavaScript que contiene pares de clave-valor, donde la clave es el nombre de la propiedad y el valor es el valor correspondiente pasado desde el componente padre.
Hay varias razones por las cuales las props se implementan de esta manera en React:
Composición de componentes: Tratar los componentes como funciones puras que aceptan props como argumentos hace que la composición de componentes sea más fácil y flexible. Puedes crear componentes pequeños y reutilizables y luego combinarlos para crear interfaces de usuario más complejas.
Reutilización de código: Al pasar datos a través de props, puedes reutilizar un componente en diferentes partes de tu aplicación simplemente proporcionando diferentes valores de props. Esto promueve la reutilización de código y reduce la duplicación.
Separación de preocupaciones: Separar la lógica del componente de los datos que maneja ayuda a mantener una clara separación de preocupaciones en tu código. El componente puede centrarse en cómo renderizar los datos (presentación) mientras que el padre se encarga de proporcionar los datos (lógica).
Inmutabilidad: Las props son inmutables, lo que significa que no se pueden modificar directamente en el componente hijo. Esto ayuda a prevenir efectos secundarios y a mantener un flujo de datos unidireccional, lo que facilita el rastreo y la depuración de errores.
Flexibilidad y extensibilidad: Al pasar props a un componente, puedes configurarlo y personalizarlo de diversas maneras. Esto hace que los componentes sean más flexibles y extensibles, lo que facilita su adaptación a diferentes necesidades y casos de uso.
En nuestro ejempro, las propiedades del componente Suma se verian de esta forma.
Acceso a las props en el componente hijo
Dentro del componente hijo, las props están disponibles como un objeto y puedes acceder a ellas utilizando la sintaxis de punto o de corchetes.
Se pasan varias props al componente Suma, incluyendo un número, un booleano, una cadena, un arreglo, un objeto y una función.
En el modulo tenemos el siguiente codigo.
import React from'react';
import PropTypes from'prop-types';
// Esta es la documentacion de un elemento
/**
* Componente Suma.
*
* @paramnumero.
* @paramValor boleano.
* @paramcadena (String).
* @paramarreglo (Array).
* @paramobjeto.
* @paramFuncion.
* @type Numericos
* @returns no regresa valor
* @defaultValue no hay valor
*
*/
const Suma = (props) =>{
console.log("ojeto props",props);
return (
<>
<p>numero {props.numero}</p>
<p>boleano {String(props.boleano)}</p>
<p>cadena {props.cadena}</p>
<p>arreglo {props.arreglo[0]}</p>
<p>objeto {JSON.stringify(props.objeto)}</p>
<p>objeto uso de color : {props.objeto.color}</p>
<p>objeto uso de tamaño : {props.objeto.tamano}</p>
<p>objeto uso del arreglo tipo[0] :{props.objeto.tipos[0]}</p>
<p>objeto uso del arreglo tipo[1] :{props.objeto.tipos[1]}</p>
<p>objeto uso del arreglo tipo[2] :{props.objeto.tipos[2]}</p>
<p>funcion {props.funcion()}</p>
</>
);
};
//Validación de parametros
Suma.propTypes = {
//no hay
};
exportdefault Suma;
Explicacion simple
<p>numero {props.numero}</p>: Renderiza un número que se pasa como prop (props.numero).
<p>boleano {String(props.boleano)}</p>: Renderiza un valor booleano que se pasa como prop (props.boleano). La función String() se usa para convertir el valor booleano en una cadena.
<p>cadena {props.cadena}</p>: Renderiza una cadena que se pasa como prop (props.cadena).
<p>arreglo {props.arreglo[0]}</p>: Renderiza el primer elemento de un arreglo que se pasa como prop (props.arreglo).
<p>objeto {JSON.stringify(props.objeto)}</p>: Renderiza un objeto que se pasa como prop (props.objeto). JSON.stringify() se utiliza para convertir el objeto en una cadena JSON.
<p>objeto uso de color : {props.objeto.color}</p>: Accede a la propiedad color de un objeto que se pasa como prop (props.objeto).
<p>objeto uso de tamaño : {props.objeto.tamano}</p>: Accede a la propiedad tamano de un objeto que se pasa como prop (props.objeto).
<p>objeto uso del arreglo tipo[0] :{props.objeto.tipos[0]}</p>: Accede al primer elemento del arreglo tipos dentro de un objeto que se pasa como prop (props.objeto).
<p>objeto uso del arreglo tipo[1] :{props.objeto.tipos[1]}</p>: Accede al segundo elemento del arreglo tipos dentro de un objeto que se pasa como prop (props.objeto).
<p>objeto uso del arreglo tipo[2] :{props.objeto.tipos[2]}</p>: Accede al tercer elemento del arreglo tipos dentro de un objeto que se pasa como prop (props.objeto).
<p>funcion {props.funcion()}</p>: Renderiza el resultado de una función que se pasa como prop (props.funcion). La función se invoca utilizando los paréntesis ().
En pantalla se visualiza de esta forma.
Desestructurar un objeto
En el codigo anterior se puede realizar una desestructuracion del objeto props y quedaria de la siguiente forma.
<p>objeto uso del arreglo tipo[0] :{objeto.tipos[0]}</p>
<p>objeto uso del arreglo tipo[1] :{objeto.tipos[1]}</p>
<p>objeto uso del arreglo tipo[2] :{objeto.tipos[2]}</p>
<p>funcion {funcion()}</p>
</>
);
};
La línea const {numero, boleano, cadena, arreglo, objeto, funcion} = props; es una forma de desestructurar un objeto en JavaScript, se esplicara lo que esta sucediendo.
props es un objeto que contiene todas las props pasadas al componente.
const {numero, boleano, cadena, arreglo, objeto, funcion}: Esto desestructura el objeto props, extrayendo las propiedades individuales numero, boleano, cadena, arreglo, objeto y funcion del objeto props y asignándolas a variables con los mismos nombres.
si tienes una prop numero que se pasa al componente, puedes acceder a su valor directamente utilizando la variable numero en lugar de props.numero.
props.children
es una propiedad especial que permite que un componente contenga otro componente o elementos HTML como su contenido. Esta propiedad es especialmente útil cuando deseas pasar contenido arbitrario a un componente, ya que te permite envolver contenido dentro de las etiquetas de apertura y cierre del componente y acceder a él desde dentro del componente.
Por ejemplo, supongamos que tienes un componente Panel que debe envolver cualquier contenido que se le pase como hijos dentro de un contenedor con un estilo específico.
Puedes hacerlo utilizando props.children de esta manera:
function Panel(props) {
return (
<div className="panel">
{props.children}
</div>
);
}
// Uso del componente Panel
<Panel>
<h2>Título del Panel</h2>
<p>Contenido del Panel</p>
</Panel>
En este ejemplo, el contenido entre las etiquetas de apertura y cierre del componente Panel (es decir, <h2>Título del Panel</h2> y <p>Contenido del Panel</p>) se pasa al componente Panel como props.children. Dentro del componente Panel, puedes renderizar props.children donde quieras que aparezca el contenido.
Continuando con nustro ejercicio suma , le cambiaremos el nombre a "MiModulo" y quedaria de esta manera con todo lo visto anterior mente
<p>objeto uso del arreglo tipo[0] :{objeto.tipos[0]}</p>
<p>objeto uso del arreglo tipo[1] :{objeto.tipos[1]}</p>
<p>objeto uso del arreglo tipo[2] :{objeto.tipos[2]}</p>
<p>funcion {funcion()}</p>
</>
);
};
//Validación de parametros
MiModulo.propTypes = {
numero:PropTypes.number.isRequired,
boleano:PropTypes.bool.isRequired,
cadena:PropTypes.string.isRequired,
arreglo:PropTypes.array.isRequired,
objeto:PropTypes.object.isRequired,
funcion:PropTypes.func.isRequired,
};
MiModulo.defaultProps = {
numero:1,
boleano:true,
cadena:"",
arreglo:[],
objeto:{},
funcion:{}
};
exportdefault MiModulo;
Una instancia
La instancia se refiere a una copia individual de un componente que se crea y se utiliza dentro de la aplicación. Cada vez que se instancia un componente, se crea una nueva copia de ese componente que puede ser renderizada y utilizada en la interfaz de usuario.
Aquí hay algunos puntos clave sobre las instancias en React
Creación de instancias: Cuando un componente de React se renderiza en la interfaz de usuario, se crea una instancia de ese componente. Esto implica crear una nueva copia del componente en la memoria y configurarla con las props y el estado necesarios.
Independencia: Cada instancia de un componente es independiente de las demás instancias y tiene su propio conjunto de props y estado. Esto significa que los cambios en una instancia no afectan a las demás instancias del mismo componente.
Reutilización: Los componentes en React están diseñados para ser reutilizables, lo que significa que una misma definición de componente puede ser instanciada y utilizada en múltiples lugares de la aplicación. Esto permite construir interfaces de usuario modulares y escalables.
Composición: La composición es una técnica fundamental en React donde los componentes se combinan para formar interfaces de usuario más complejas. Al instanciar componentes individuales y componerlos juntos, se puede construir una interfaz de usuario completa y funcional.
Ciclo de vida: Cada instancia de un componente tiene su propio ciclo de vida, que incluye eventos como montaje, actualización y desmontaje. Estos eventos se manejan automáticamente por React y permiten realizar acciones específicas en cada etapa del ciclo de vida de la instancia.
Ciclo de vida de una instancia
Montaje (Mounting)
Esta etapa ocurre cuando se instancia por primera vez un componente y se agrega al DOM.
Eventos asociados:
constructor(): Se llama antes de que el componente sea montado. Se utiliza para inicializar el estado del componente y enlazar métodos.
render(): Se llama para renderizar el componente y generar la descripción de la interfaz de usuario.
componentDidMount(): Se llama después de que el componente ha sido montado en el DOM. Se utiliza para realizar operaciones de inicialización que requieran acceso al DOM, como solicitudes de datos a un servidor.
getDerivedStateFromProps:Este método estática se llama justo antes de renderizar, tanto en la montura inicial como en las actualizaciones posteriores, inmediatamente después de recibir nuevas props. Reemplazó al método componentWillReceiveProps, que ahora se considera obsoleto.
Actualización (Updating)
Esta etapa ocurre cuando el componente se actualiza debido a cambios en las props o en el estado.
Eventos asociados:
render(): Se llama para volver a renderizar el componente y generar una nueva descripción de la interfaz de usuario.
componentDidUpdate(): Se llama después de que el componente ha sido actualizado en el DOM. Se utiliza para realizar operaciones adicionales después de una actualización, como solicitudes de datos adicionales.
getSnapshotBeforeUpdate():Este método se invoca justo antes de que los cambios se apliquen al DOM, por lo que es útil para realizar algunas operaciones que dependen del estado del DOM antes de que se actualice
Desmontaje (Unmounting)
Esta etapa ocurre cuando el componente es eliminado del DOM.
Eventos asociados:
componentWillUnmount(): Se llama justo antes de que el componente sea desmontado y eliminado del DOM. Se utiliza para realizar limpieza y liberar recursos, como cancelar suscripciones a eventos o temporizadores.
El renderizado
El renderizado en una representación virtual es el proceso en el que React interpreta la estructura de un componente y genera una representación abstracta de la interfaz de usuario en la memoria, conocida como árbol de elementos virtuales. Este árbol de elementos virtuales está compuesto por objetos JavaScript que describen la estructura y los elementos de la interfaz de usuario, pero aún no se han convertido en elementos reales del DOM.
Cuando se renderiza un componente en React, la función de renderización del componente se ejecuta para generar una descripción de cómo debería verse el componente en la interfaz de usuario. Esta función de renderización devuelve elementos de React (generalmente escritos en JSX) que representan la estructura y los elementos del componente.
React utiliza esta representación virtual para realizar comparaciones eficientes y determinar los cambios que deben aplicarse al DOM real. En lugar de interactuar directamente con el DOM cada vez que se produce un cambio, React compara la representación virtual actual con la representación virtual anterior y determina cuáles son las diferencias. Luego, aplica estos cambios al DOM real de manera eficiente para reflejar los cambios en la interfaz de usuario.
El uso de una representación virtual permite a React optimizar el rendimiento al minimizar la cantidad de manipulación del DOM necesario y al realizar actualizaciones de manera más eficiente. Además, proporciona un modelo de programación declarativo donde los componentes se definen en términos de cómo deberían verse en lugar de en términos de cómo se deben actualizar en el DOM, lo que facilita la creación de interfaces de usuario dinámicas y receptivas.
El proceso de renderizado de un componente en React implica varios pasos que se llevan a cabo internamente por la biblioteca. A continuación, se describen los pasos generales que ocurren durante el proceso de renderizado de un componente en React:
Se llama a la función de renderización del componente
Cuando se instancia un componente en React , se llama a su función de renderización. Esta función es responsable de devolver la descripción de cómo debería ser la interfaz de usuario del componente en forma de elementos de React (generalmente escritos en JSX).
Se genera la representación virtual del componente:
La función de renderización devuelve una descripción de la interfaz de usuario del componente en forma de elementos de React. React utiliza esta descripción para construir una representación virtual del componente, que es un árbol de elementos virtuales en la memoria.
Se compara la representación virtual con la representación anterior:
Una vez que se genera la representación virtual del componente, React la compara con la versión anterior de la representación virtual (si existe). Esta comparación determina cuáles son los cambios que deben aplicarse al DOM real para reflejar la nueva representación del componente.
Se determinan los cambios necesarios:
React determina qué cambios deben aplicarse al DOM real para reflejar la nueva representación virtual del componente. Esto implica identificar nuevos elementos que deben agregarse, elementos existentes que deben actualizarse y elementos que deben eliminarse.
Se aplican los cambios al DOM real de manera eficiente:
Una vez que se determinan los cambios necesarios, React aplica estos cambios al DOM real de manera eficiente. Esto puede implicar agregar nuevos elementos al DOM, actualizar el contenido o los atributos de los elementos existentes y eliminar elementos que ya no están presentes en la representación virtual.
Se actualiza el estado interno del componente:
Después de que se aplican los cambios al DOM real, React actualiza el estado interno del componente si es necesario. Esto puede implicar la actualización del estado local del componente o la llamada a métodos de ciclo de vida del componente, como componentDidUpdate.
Se completa el ciclo de renderizado:
Una vez que se han aplicado todos los cambios y se ha actualizado el estado interno del componente, se completa el ciclo de renderizado del componente. El componente está ahora en un estado actualizado y listo para responder a interacciones del usuario u otros eventos que puedan ocurrir.
El renderizado del componente puede ocurrir por varias razones, incluyendo:
Montaje inicial: Cuando un componente se monta por primera vez en el DOM, se renderiza inicialmente para mostrar su contenido en la interfaz de usuario.
Actualización de estado o props: Cuando el estado interno de un componente o las props que recibe cambian, el componente se vuelve a renderizar para reflejar estos cambios en la interfaz de usuario.
Contexto cambia: Si un componente depende del contexto proporcionado por un componente padre o un proveedor de contexto, se volverá a renderizar cuando ese contexto cambie.
Fuerza de actualización: A veces, es necesario forzar la actualización de un componente, por ejemplo, si se reciben nuevos datos de un servidor o si se produce un cambio en la aplicación que requiere una actualización de la interfaz de usuario.
Instancia y Renderizado
En la ejecucion primero se ejecuta la creación de la instancia del componente y luego se realiza el proceso de renderizado.
Instanciación del componente:
Cuando un componente de React se utiliza en la aplicación, se crea una instancia del componente. Esto implica crear una nueva copia del componente en la memoria y configurarla con las props y el estado necesarios.
Durante la instanciación del componente, se inicializan sus propiedades, estado y otros datos necesarios para el renderizado.
Renderizado del componente:
Después de que se instancia el componente, React llama a la función de renderizado del componente para obtener una descripción de cómo debería verse el componente en la interfaz de usuario.
Esta función de renderizado devuelve elementos de React que representan la estructura de la interfaz de usuario del componente.
Los elementos de React devueltos por la función de renderizado se utilizan para construir una representación virtual del componente en la memoria.
Esta representación virtual se compara con la representación virtual anterior (si existe) para determinar los cambios necesarios en el DOM real.
Finalmente, se aplican estos cambios al DOM real para actualizar la interfaz de usuario en consecuencia.
Agregar interactividad
Algunas cosas en la pantalla se actualizan en respuesta a la entrada del usuario. Por ejemplo, hacer clic en una galería de imágenes cambia la imagen activa. En React, los datos que cambian con el tiempo se denominan estado. Puedes agregar estado a cualquier componente y actualizarlo según sea necesario. En este capítulo, aprenderás a escribir componentes que controlen interacciones, actualicen tu estado y muestren resultados diferentes a lo largo del tiempo.
Hook
En React, un hook es una función especial que te permite agregar características de React a componentes funcionales. Los hooks fueron introducidos en React 16.8 como una forma de usar el estado y otras características de React sin tener que escribir clases.
Los hooks proporcionan una manera de reutilizar la lógica de estado y efectos secundarios en los componentes funcionales, lo que los hace más flexibles y fáciles de mantener. Antes de los hooks, la lógica de estado y los efectos secundarios solo se podían utilizar en componentes de clase, lo que a menudo resultaba en código más complicado y menos legible.
Los hooks tienen nombres que comienzan con "use" (por ejemplo, useState, useEffect, useContext, etc.) y pueden ser utilizados dentro de los componentes funcionales de React. Cada hook tiene una función específica: por ejemplo, useState se utiliza para agregar estado a un componente funcional, useEffect se utiliza para realizar efectos secundarios, useContext se utiliza para acceder al contexto de React, entre otros.
Los hooks se utilizan llamando a estas funciones dentro del cuerpo de un componente funcional. Esto permite a los desarrolladores escribir código más limpio y modular al separar la lógica de estado y los efectos secundarios de la representación de la interfaz de usuario.
El estado: la memoria de un componente
Los componentes a menudo necesitan cambiar lo que aparece en la pantalla como resultado de una interacción. Escribir en el formulario debería actualizar el campo de entrada, hacer clic en «siguiente» en un carrusel de imágenes debería cambiar la imagen que se muestra, hacer clic en «comprar» pone un producto en el carrito de compras. Los componentes necesitan «recordar» cosas: el valor de entrada actual, la imagen actual, el carrito de compras. En React, este tipo de memoria específica del componente se llama estado.
Puedes agregar estado a un componente con un useState Hook. Los Hooks son funciones especiales que permiten que tus componentes usen funciones de React (el estado es una de esas funciones). El Hook useState te permite declarar una variable de estado. Toma el estado inicial y devuelve un par de valores: el estado actual y una función de establecimiento de estado que te permite actualizarlo.
useState
useState es un hook de React que permite a los componentes funcionales tener estados locales. Almacenar un valor en un estado utilizando useState implica definir un estado y una función para actualizarlo. Por ejemplo:
Esto crea un estado myState con un valor inicial de "someValue". El hook useState devuelve un par de valores: el valor actual del estado (myState) y una función para actualizar ese estado (setMyState). Cuando se llama a setMyState con un nuevo valor, React se encarga de actualizar el estado y volver a renderizar el componente si es necesario, lo que a su vez actualiza la interfaz de usuario para reflejar el cambio en el estado.
Alcance de variable de estado y una variable definida con let o const
Alcance de una variable de estado (useState):
Las variables de estado creadas con useState son específicas de un componente funcional en React. Esto significa que solo pueden ser accedidas y modificadas dentro del componente en el que fueron definidas.
No se pueden acceder ni modificar fuera del componente en el que se declararon, ni tampoco pueden ser compartidas entre diferentes componentes sin alguna técnica adicional como el uso de props, context, o elevación de estados.
El alcance de una variable de estado está limitado al componente en el que se encuentra y a sus componentes hijos.
Alcance de una variable declarada con let o const:
Las variables declaradas con let o const tienen un alcance de bloque en JavaScript. Esto significa que su alcance está limitado al bloque de código en el que fueron declaradas.
Pueden ser accedidas y modificadas dentro del bloque en el que fueron definidas, así como en bloques anidados dentro de ese bloque.
Sin embargo, no pueden ser accedidas desde fuera del bloque en el que fueron definidas, y si se intenta acceder a ellas fuera de ese bloque, se generará un error.
Ejemplo del uso de una variable de estado (useState)
// Definimos el estado 'count' utilizando useState
// El primer elemento del array retornado por useState es el valor del estado
// El segundo elemento es una función que permite actualizar ese estado
// Entre los parentesis de useState colocamos el valor inicial del estado
const [count, setCount] = useState(0);
// Función para incrementar el contador
const increment = () => {
// Utilizamos la función setCount para actualizar el valor del estado 'count'
// Al llamar a setCount, React re-renderiza el componente con el nuevo valor de 'count'
setCount(count + 1);
};
// Función para decrementar el contador
const decrement = () => {
// Utilizamos la función setCount para actualizar el valor del estado 'count'
// Al llamar a setCount, React re-renderiza el componente con el nuevo valor de 'count'
setCount(count - 1);
};
return (
<div>
<h1>Contador: {count}</h1>
{/* Botón para incrementar el contador */}
<buttononClick={increment}>Incrementar</button>
{/* Botón para decrementar el contador */}
<buttononClick={decrement}>Decrementar</button>
</div>
);
}
exportdefault Contador;
useEffect
El hook useEffect es una función proporcionada por React que se utiliza para realizar efectos secundarios en componentes funcionales. Estos efectos secundarios pueden incluir operaciones como suscripciones a eventos, solicitud de datos, actualización del DOM, entre otros. useEffect se ejecuta después de que el componente se haya renderizado en el DOM y en cada actualización subsiguiente.
El hook useEffect acepta dos argumentos: una función de efecto y una lista de dependencias opcional. La función de efecto es donde se colocan las operaciones que se desean realizar. Esta función se ejecutará después de que el componente se haya renderizado en el DOM y en cada actualización subsiguiente, a menos que se especifiquen dependencias y estas no cambien entre actualizaciones.
La lista de dependencias es un arreglo opcional que se pasa como segundo argumento a useEffect. Esta lista se utiliza para especificar qué variables deben ser monitoreadas por useEffect. Si alguna de estas variables cambia entre renderizados, la función de efecto se volverá a ejecutar. Si la lista de dependencias está vacía, la función de efecto se ejecutará solo una vez después del primer renderizado.
// Limpiar el intervalo cuando el componente se desmonta o cuando el contador alcanza cierto valor
return () => {
clearInterval(intervalo);
};
}, [contador]); // La dependencia 'contador' asegura que el efecto se ejecute cada vez que 'contador' cambie
// Renderizar el contador
return (
<div>
{/* verifica que el estado sea diferente de null con el operador && (AND) */}
{contador !== null && `Contador: ${contador}`}
</div>
);
}
exportdefault Contador;
useRef
El hook useRef es una función proporcionada por React que se utiliza para crear una referencia mutable que puede ser accedida y modificada en un componente funcional. Las referencias son objetos que nos permiten acceder a un elemento del DOM o a un componente de React de manera directa.
El hook useRef devuelve un objeto de referencia que persiste a lo largo de los renderizados del componente. Esto significa que el objeto de referencia no se ve afectado por las actualizaciones del componente y mantiene su valor entre renderizados.
Acceso al DOM: Puedes utilizar useRef para acceder directamente a los nodos del DOM en un componente funcional. Esto es útil cuando necesitas medir o modificar elementos del DOM de forma imperativa, como enfocar un input o modificar sus estilos.
Almacenamiento de valores mutables: Puedes utilizar useRef para almacenar valores que persistan entre renderizaciones del componente. A diferencia del estado (useState), los cambios en el valor de useRef no provocan una re-renderización del componente.
Preservación de valores entre renderizaciones: El valor almacenado en useRef permanece igual entre re-renderizaciones del componente, incluso si el componente se vuelve a montar. Esto es útil para mantener referencias a objetos o valores que necesitas conservar entre renderizaciones.
El hook useMemo en React se utiliza para memoizar el resultado de una función de cálculo en un componente funcional. Esto significa que puedes utilizar useMemo para almacenar en caché el resultado de una función y evitar que se recalcule en cada renderizado del componente, a menos que las dependencias de esa función cambien.
La función useMemo acepta dos argumentos: una función de cálculo y una lista de dependencias. La función de cálculo es una función que realiza algún tipo de cálculo costoso o computacionalmente intensivo. Esta función se ejecutará cada vez que el componente se renderice, pero el resultado se memoizará y se devolverá como el resultado de useMemo.
La lista de dependencias es un arreglo opcional que se pasa como segundo argumento a useMemo. Esta lista se utiliza para especificar qué variables deben ser monitoreadas por useMemo. Si alguna de estas variables cambia entre renderizados, la función de cálculo se volverá a ejecutar para recalcular el resultado. Si la lista de dependencias está vacía, la función de cálculo se ejecutará solo una vez después del primer renderizado.
El uso de useMemo es útil cuando tienes una función costosa en términos de rendimiento que se llama dentro de un componente funcional, pero cuyos resultados no cambian a menos que las dependencias cambien. Al memoizar el resultado de esta función con useMemo, puedes mejorar el rendimiento de tu aplicación al evitar cálculos innecesarios en cada renderizado.
Una "Función de cálculo costoso" en React, que sería apropiada para memoizar con useMemo, podría ser cualquier operación que requiera una cantidad significativa de recursos computacionales o tiempo de procesamiento. Algunos ejemplos de estos procesos costosos podrían incluir:
Operaciones matemáticas complejas: Cálculos intensivos que involucran algoritmos complejos, como cálculos de matrices, algoritmos de búsqueda o algoritmos de ordenamiento con grandes conjuntos de datos.
Operaciones de procesamiento de imágenes: Manipulaciones de imágenes que requieren transformaciones complejas, como el procesamiento de filtros, el ajuste del brillo y el contraste, la detección de bordes, la segmentación de imágenes, etc.
Operaciones de análisis de datos: Procesamiento de grandes conjuntos de datos para realizar operaciones como agregaciones, filtrado, mapeo, reducción, etc., en aplicaciones de análisis de datos o visualización de datos.
Operaciones de simulación o modelado: Simulaciones numéricas o modelos matemáticos complejos que implican múltiples iteraciones y cálculos repetitivos, como simulaciones físicas, modelos de comportamiento, etc.
Operaciones de procesamiento de texto: Procesamiento de texto que involucra análisis lingüístico, búsqueda de patrones, análisis de sentimientos, traducción de idiomas, generación de resúmenes, etc.
La "Función de cálculo costoso" puede referirse a cualquier operación que requiera un esfuerzo computacional significativo. El uso de useMemo en React para memoizar el resultado de estas funciones puede mejorar el rendimiento de la aplicación al evitar cálculos innecesarios en cada renderizado del componente.
useCallback
El hook useCallback en React se utiliza para memoizar una función callback, de modo que esta no se vuelva a crear en cada renderizado del componente a menos que sus dependencias cambien. Esto es útil cuando pasas funciones a componentes hijos, ya que evita que esos componentes se vuelvan a renderizar innecesariamente cada vez que el componente padre se renderiza.
El hook useCallback acepta dos argumentos: la función callback que deseas memoizar y una lista de dependencias opcional. La función callback es la que quieres memoizar para evitar su recreación en cada renderizado. La lista de dependencias es un arreglo opcional que especifica las variables que la función callback utiliza. Si alguna de estas variables cambia, la función callback se recreará; de lo contrario, se devolverá la misma instancia de función.
// Componente hijo que recibe la función incrementar como prop
function BotonIncrementar({ incrementar }) {
return (
<buttononClick={incrementar}>Incrementar</button>
);
}
exportdefault Contador;
useContext
useContext está relacionado con la gestión de contextos, que es una forma de pasar datos a través del árbol de componentes sin tener que pasar props manualmente en cada nivel.
Creación del Contexto: Para empezar, debes crear un contexto utilizando la función createContext de React. Este contexto actuará como un contenedor para los datos que deseas compartir.
exportconst ContextoUsuario = createContext();
Proveer el Contexto: Luego, utilizas un componente Provider para envolver la parte de tu aplicación donde deseas que el contexto esté disponible. Este componente acepta un prop llamado value que proporciona el valor actual del contexto.
<ContextoUsuario.Provider>
Consumir el Contexto: Ahora, en cualquier componente hijo dentro del Provider, puedes utilizar el hook useContext para acceder al valor del contexto.
const { usuario } = useContext(ContextoUsuario);
Actualización del Contexto: Si el valor del contexto cambia en algún lugar de la aplicación, todos los componentes que consumen ese contexto se volverán a renderizar con el nuevo valor.
Un custom hook (gancho personalizado) en React es una función de JavaScript que permite reutilizar la lógica relacionada con los hooks de React en diferentes componentes. Los custom hooks siguen la misma convención de nomenclatura que los hooks estándar de React, comenzando con el prefijo use.
¿Por qué usar un custom hook?
Los custom hooks son útiles cuando tienes lógica compleja que necesitas compartir entre varios componentes. En lugar de duplicar código, puedes encapsular esa lógica en un custom hook y simplemente reutilizarlo en los componentes que lo necesiten.
Creación de un custom hook
Un custom hook se crea como una función de JavaScript que puede utilizar otros hooks de React como useState, useEffect, useContext, etc. Aquí tienes un ejemplo sencillo:
import { useState, useEffect } from'react';
// Custom hook para manejar el estado de una ventana
}, []); // El array vacío asegura que el efecto se ejecute solo una vez
return width;
}
exportdefault useWindowWidth;
Uso de un custom hook
Para usar un custom hook en un componente, simplemente lo llamas como lo harías con cualquier otro hook:
import React from'react';
import useWindowWidth from'./useWindowWidth'; // Importa el custom hook
function MiComponente() {
const width = useWindowWidth(); // Usa el custom hook
return (
<div>
<h1>El ancho de la ventana es: {width}px</h1>
</div>
);
}
exportdefault MiComponente;
Beneficios de los custom hooks
Reutilización de Lógica: Evitas la duplicación de código y mantienes la lógica centralizada.
Abstracción: Encapsulas lógica compleja dentro de un hook, lo que hace que tus componentes sean más simples y fáciles de entender.
Composición: Puedes combinar múltiples hooks estándar de React o incluso otros custom hooks dentro de un custom hook.
Consideraciones
Un custom hook puede devolver cualquier tipo de valor: un estado, una función, un objeto, etc.
Siguen las mismas reglas que los hooks estándar: deben llamarse al nivel superior de la función, no dentro de bucles, condicionales, o funciones anidadas.
Manejo de eventos
En React, puedes manejar una amplia variedad de eventos que ocurren en los elementos DOM, así como eventos personalizados definidos por el usuario. Algunos de los eventos DOM más comunes que puedes manejar en React incluyen:
onClick: Se dispara cuando se hace clic en un elemento.
onChange: Se dispara cuando el valor de un elemento de formulario cambia.
onSubmit: Se dispara cuando se envía un formulario.
onKeyDown, onKeyPress, onKeyUp: Se disparan cuando se presionan teclas en un elemento.
onMouseOver, onMouseOut: Se disparan cuando el mouse se mueve sobre un elemento.
onFocus, onBlur: Se disparan cuando un elemento obtiene o pierde el foco.
onScroll: Se dispara cuando se desplaza un elemento.
Estos son solo algunos ejemplos de eventos que puedes manejar en React. Hay muchos otros eventos disponibles que puedes utilizar según tus necesidades. Además, puedes crear tus propios eventos personalizados utilizando el sistema de eventos de React.
onClick: Se activa cuando se hace clic en un elemento.
function handleClick() {
console.log('Botón clickeado');
}
<button onClick={handleClick}>Click aquí</button>
onChange: Se activa cuando el valor de un elemento cambia, como en un input.
function handleChange(event) {
console.log('Nuevo valor:', event.target.value);
}
<input type="text" onChange={handleChange} />
onSubmit: Se activa cuando se envía un formulario.
function handleSubmit(event) {
event.preventDefault();
console.log('Formulario enviado');
}
<form onSubmit={handleSubmit}>
<button type="submit">Enviar</button>
</form>
onFocus: Se activa cuando un elemento recibe el foco.
function handleFocus() {
console.log('Elemento enfocado');
}
<input type="text" onFocus={handleFocus} />
onKeyDown, onKeyPress, onKeyUp: Se activan cuando se presionan, se presionan y se liberan las teclas, respectivamente.
function handleKeyDown(event) {
console.log('Tecla presionada:', event.key);
}
<input type="text" onKeyDown={handleKeyDown} />
onMouseOver, onMouseOut: Se activan cuando el puntero del mouse entra o sale de un elemento.
function handleMouseOver() {
console.log('Mouse sobre el elemento');
}
<div onMouseOver={handleMouseOver}>Pasar el mouse aquí</div>
<divonMouseOver={handleMouseOver}>Pasar el mouse aquí</div>
</>
)
Listas y keys
Primero, vamos a revisar como transformas listas en Javascript.
Dado el código de abajo, usamos la función map() para tomar un array de numbers y duplicar sus valores. Asignamos el nuevo array devuelto por map() a la variable doubled y la mostramos:
const numbers =[1,2,3,4,5];const doubled = numbers.map((number)=> number *2);console.log(doubled);
Este código muestra [2, 4, 6, 8, 10] a la consola.
En React, transformar arrays en listas de elementos es casi idéntico.
Renderizado de Múltiples Componentes
Puedes hacer colecciones de elementos e incluirlos en JSX usando llaves {}.
Debajo, recorreremos el array numbers usando la función map() de Javascript. Devolvemos un elemento <li> por cada ítem . Finalmente, asignamos el array de elementos resultante a listItems:
Entonces, podemos incluir el array listItems completo dentro de un elemento <ul>:
<ul>{listItems}</ul>A
Keys
Las keys ayudan a React a identificar que ítems han cambiado, son agregados, o son eliminados. Las keys deben ser dadas a los elementos dentro del array para darle a los elementos una identidad estable:
La mejor forma de elegir una key es usando un string que identifique únicamente a un elemento de la lista entre sus hermanos. Habitualmente vas a usar IDs de tus datos como key:
Cuando no tengas IDs estables para renderizar, puedes usar el índice del ítem como una key como último recurso:
const todoItems = todos.map((todo, index)=>// Only do this if items have no stable IDs<likey={index}>{todo.text}</li>);
No recomendamos usar índices para keys si el orden de los ítems puede cambiar. Esto puede impactar negativamente el rendimiento y puede causar problemas con el estado del componente. Revisa el artículo de Robin Pokorny para una explicación en profundidad de los impactos negativos de usar un índice como key. Si eliges no asignar una key explícita a la lista de ítems, React por defecto usará índices como keys.
Las keys solo tienen sentido en el contexto del array que las envuelve.
Por ejemplo, si extraes un componente ListItem, deberías mantener la key en los elementos <ListItem /> del array en lugar de en el elemento <li> del propio ListItem.
Ejemplo: Uso Incorrecto de Key
functionListItem(props){const value = props.value;return(// Mal! No hay necesidad de especificar la key aquí:<likey={value.toString()}>{value}</li>);}functionNumberList(props){const numbers = props.numbers;const listItems = numbers.map((number)=>// Mal! La key debería haber sido especificada aquí:<ListItemvalue={number}/>);return(<ul>{listItems}</ul>);}
Las keys deben ser únicas solo entre hermanos
Las keys usadas dentro de arrays deberían ser únicas entre sus hermanos. Sin embargo, no necesitan ser únicas globalmente. Podemos usar las mismas keys cuando creamos dos arrays diferentes:
functionBlog(props){const sidebar =(<ul>{props.posts.map((post)=><likey={post.id}>{post.title}</li>)}</ul>);const content = props.posts.map((post)=><divkey={post.id}><h3>{post.title}</h3><p>{post.content}</p></div>);return(<div>{sidebar}<hr/>{content}</div>);}const posts =[{id:1,title:'Hello World',content:'Welcome to learning React!'},{id:2,title:'Installation',content:'You can install React from npm.'}];const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Blogposts={posts}/>);
localStorage
Es un objeto proporcionado por los navegadores web modernos que permite a las aplicaciones web almacenar datos de forma persistente en el navegador. Estos datos permanecen disponibles incluso después de que se cierre el navegador y se vuelva a abrir, lo que los hace útiles para almacenar información localmente en la máquina del usuario.
localStorage utiliza un sistema de clave-valor para almacenar datos. Puede almacenar cadenas de texto (strings) y recuperarlas más tarde utilizando una clave específica.
Algunos usos comunes de localStorage incluyen:
Almacenamiento de preferencias de usuario: Puede usar localStorage para recordar las preferencias del usuario, como temas de color, idiomas preferidos, etc.
Almacenamiento de datos de sesión: Puede usar localStorage para almacenar datos temporales durante la sesión del usuario, como datos de formulario no enviados, estados de aplicación, etc.
Caché de datos: Puede usar localStorage para almacenar datos estáticos que no cambian con frecuencia y que se pueden recuperar rápidamente, como datos de configuración o datos de referencia.
Ejemplo de cómo usar localStorage en JavaScript:
// Almacenar un valor en localStorage
localStorage.setItem('clave', 'valor');
// Recuperar un valor de localStorage
const valor = localStorage.getItem('clave');
// Eliminar un valor de localStorage
localStorage.removeItem('clave');
Es importante tener en cuenta que los datos almacenados en localStorage están disponibles para cualquier script que se ejecute en el mismo origen (es decir, en la misma combinación de protocolo, nombre de dominio y puerto). Sin embargo, el uso excesivo de localStorage puede afectar negativamente al rendimiento y la seguridad de una aplicación, por lo que debe usarse con moderación y precaución.
sessionStorage
Es un objeto proporcionado por los navegadores web modernos que permite a las aplicaciones web almacenar datos de forma similar a localStorage, pero con una vida útil limitada a la duración de la sesión de navegación del usuario. Esto significa que los datos almacenados en sessionStorage están disponibles solo mientras la pestaña o ventana del navegador está abierta y se pierden cuando se cierra.
Al igual que localStorage, sessionStorage utiliza un sistema de clave-valor para almacenar datos y proporciona métodos para almacenar, recuperar y eliminar datos. Sin embargo, a diferencia de localStorage, los datos almacenados en sessionStorage no persisten más allá de la sesión actual del navegador.
sessionStorage es útil para almacenar información temporal durante la sesión del usuario, como datos de autenticación, estados de la aplicación, datos de formularios no enviados, etc. Puede ser particularmente útil en aplicaciones web que requieren una autenticación de sesión y necesitan almacenar datos específicos del usuario mientras el usuario está activo en la aplicación.
Aquí hay un ejemplo básico de cómo usar sessionStorage en JavaScript:
// Almacenar un valor en sessionStorage
sessionStorage.setItem('clave', 'valor');
// Recuperar un valor de sessionStorage
const valor = sessionStorage.getItem('clave');
// Eliminar un valor de sessionStorage
sessionStorage.removeItem('clave');
Al igual que con localStorage, los datos almacenados en sessionStorage están disponibles para cualquier script que se ejecute en la misma combinación de protocolo, nombre de dominio y puerto. Sin embargo, los datos se borran automáticamente cuando se cierra la sesión del navegador o se abre una nueva pestaña o ventana.
callback
Es una función que se pasa como argumento a otra función y se ejecuta después de que se completa una operación asincrónica o algún tipo de evento específico. En esencia, un callback es una forma de "llamada de vuelta" que se ejecuta más tarde, generalmente en respuesta a algún tipo de evento o acción.
Los callbacks son fundamentales en JavaScript y se utilizan ampliamente en situaciones donde las operaciones son asincrónicas, como solicitudes de red, lectura de archivos, temporizadores, eventos de usuario, etc. También son útiles para manejar eventos en aplicaciones web, como clics de botón, cambios de estado, entradas de teclado, etc.
Aquí hay un ejemplo básico de un callback en JavaScript:
function operacionAsincronica(callback) {
// Simular una operación asincrónica, como una solicitud de red
setTimeout(function() {
console.log("La operación asincrónica ha finalizado.");
// Llamar al callback proporcionado
callback();
}, 1000);
}
// Llamar a la función operacionAsincronica con un callback
operacionAsincronica(function() {
console.log("Este es el callback, se ejecuta después de la operación asincrónica.");
});
En este ejemplo, operacionAsincronica es una función que simula una operación asincrónica (una solicitud de red en este caso) y toma un callback como argumento. Una vez que se completa la operación asincrónica (después de un retraso simulado de 1 segundo en este caso), se ejecuta el callback proporcionado.
Los callbacks son una parte esencial de la programación asincrónica en JavaScript y son ampliamente utilizados en el desarrollo de aplicaciones web y otras aplicaciones que requieren manejo de eventos y operaciones no bloqueantes.
promesa
Es un objeto que representa el resultado eventual (éxito o fracaso) de una operación asincrónica. Proporciona una forma de trabajar con operaciones asíncronas de una manera más fácil y legible, evitando así el anidamiento excesivo de callbacks.
En esencia, una promesa puede tener uno de los siguientes estados:
Pendiente (pending): Estado inicial, la promesa está esperando que se cumpla o se rechace.
Cumplida (fulfilled): La operación asincrónica se completó con éxito y se resolvió la promesa con un valor.
Rechazada (rejected): La operación asincrónica falló y se rechazó la promesa con un motivo (normalmente un objeto Error).
Las promesas tienen dos métodos principales para interactuar con ellas:
then(): Se utiliza para manejar el caso de éxito de la promesa. Toma una función de callback que se ejecutará cuando la promesa se cumpla, pasando el valor resuelto como argumento.
catch(): Se utiliza para manejar el caso de error de la promesa. Toma una función de callback que se ejecutará cuando la promesa sea rechazada, pasando el motivo del rechazo (normalmente un objeto Error) como argumento.
Aquí hay un ejemplo básico de cómo se usa una promesa en JavaScript:
const promesa = new Promise((resolve, reject) => {
En React, las promesas se utilizan comúnmente para manejar operaciones asincrónicas, como solicitudes de red, lectura/escritura de archivos, etc. También se pueden combinar con async/await, una sintaxis más moderna para trabajar con código asincrónico que proporciona una forma más fácil de escribir y leer código asincrónico.
async y await
son características introducidas en ECMAScript 2017 (también conocido como ES8) que proporcionan una forma más limpia y concisa de trabajar con código asincrónico en JavaScript. Estas características están diseñadas para simplificar y hacer más legible la escritura y lectura de código asincrónico, especialmente cuando se trata de trabajar con promesas.
async: La palabra clave async se coloca antes de una función para indicar que la función devuelve una promesa. Las funciones marcadas como async siempre devuelven una promesa, incluso si no tienen un operador return. Dentro de una función async, se pueden usar las palabras clave await para esperar el resultado de una promesa antes de continuar la ejecución del código.
await: La palabra clave await se utiliza dentro de una función async para esperar la resolución de una promesa. Cuando se encuentra una expresión await, la ejecución de la función async se detiene hasta que la promesa se resuelve y devuelve su resultado. El valor resuelto de la promesa se asigna a la variable que sigue a la palabra clave await.
Veamos un ejemplo de cómo se utilizan async y await para trabajar con promesas de manera más legible:
asyncfunction obtenerDatosUsuario(id) {
try {
// Simular una solicitud de red asincrónica para obtener datos de usuario
console.log('No se pudieron obtener los datos del usuario');
}
} catch (error) {
console.error('Ocurrió un error al obtener los datos del usuario:', error);
}
}
// Llamar a la función para mostrar los datos de un usuario específico
mostrarDatosUsuario(123);
En este ejemplo, obtenerDatosUsuario es una función async que realiza una solicitud de red para obtener datos de usuario y devuelve una promesa que se resuelve con los datos del usuario. mostrarDatosUsuario es otra función async que utiliza await para esperar la resolución de la promesa devuelta por obtenerDatosUsuario, y luego muestra los datos del usuario o maneja cualquier error que ocurra durante la obtención de los datos.
El objeto history
Es parte del modelo de navegación del navegador web y proporciona una interfaz programática para interactuar con el historial de navegación del usuario. Este objeto está disponible en el entorno del navegador web y se puede acceder a él en aplicaciones web JavaScript que se ejecutan en el navegador.
El objeto history proporciona métodos y propiedades que permiten a las aplicaciones web manipular el historial de navegación del usuario, como:
Navegar hacia adelante y hacia atrás en el historial de navegación.
Agregar, reemplazar o eliminar entradas del historial.
Obtener información sobre la ubicación actual en el historial de navegación.
Escuchar cambios en el historial de navegación y reaccionar en consecuencia.
En React, el objeto history se puede acceder a través del componente BrowserRouter o HashRouter proporcionado por la biblioteca react-router-dom, que se utiliza para la navegación en aplicaciones React. Estos componentes envuelven la aplicación React y proporcionan el objeto history como una prop history al componente de enrutamiento y a los componentes secundarios.
Aquí hay un ejemplo de cómo acceder al objeto history en una aplicación React utilizando react-router-dom:
import React from'react';
import { BrowserRouter as Router, Route, Link } from'react-router-dom';
function ComponenteDeEjemplo() {
function irAPaginaAnterior() {
// Navegar hacia atrás en el historial de navegación
history.goBack();
}
return (
<div>
<h1>Componente de Ejemplo</h1>
<buttononClick={irAPaginaAnterior}>Ir a la página anterior</button>
</div>
);
}
function App() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Linkto="/">Inicio</Link>
</li>
<li>
<Linkto="/ejemplo">Ir a Ejemplo</Link>
</li>
</ul>
</nav>
<Routepath="/"exactcomponent={() =><h1>Página de Inicio</h1>}/>
En este ejemplo, el componente ComponenteDeEjemplo accede al objeto history para navegar hacia atrás en el historial de navegación cuando se hace clic en el botón. El objeto history se proporciona automáticamente por react-router-dom y está disponible en todos los componentes de la aplicación que se renderizan dentro del Router.
El objeto history que se proporciona a través de react-router-dom sigue la interfaz definida por la biblioteca history, que es una biblioteca independiente utilizada para gestionar el historial de navegación en aplicaciones web. La interfaz del objeto history puede variar según la versión específica de history que se esté utilizando, pero generalmente proporciona métodos y propiedades para interactuar con el historial de navegación del navegador.
Algunas de las propiedades y métodos comunes que pueden estar disponibles en el objeto history incluyen:
push(path, [state]): Agrega una nueva entrada al historial de navegación, navegando a la ruta especificada.
replace(path, [state]): Reemplaza la entrada actual del historial de navegación con una nueva entrada, navegando a la ruta especificada.
go(n): Navega hacia adelante o hacia atrás en el historial de navegación por el número especificado de pasos.
goBack(): Navega hacia atrás en el historial de navegación, equivalente a history.go(-1).
goForward(): Navega hacia adelante en el historial de navegación, equivalente a history.go(1).
location: Proporciona información sobre la ubicación actual en el historial de navegación, como la URL actual y el estado asociado.
listen(listener): Registra un oyente para escuchar cambios en el historial de navegación y ejecutar una función de devolución de llamada cuando ocurren cambios.
La estructura específica del objeto history puede variar dependiendo de la implementación y la versión de la biblioteca de enrutamiento utilizada. Se recomienda consultar la documentación oficial de react-router-dom y history para obtener detalles específicos sobre cómo acceder y utilizar el objeto history en una aplicación React.
función jumpto
La función jumpto no es una función estándar de React o de alguna de sus bibliotecas relacionadas como react-router-dom. Si estás buscando una función para realizar una navegación programática en una aplicación React, puedes utilizar métodos proporcionados por history o componentes de enrutamiento como Link o NavLink de react-router-dom.
Por ejemplo, si deseas navegar a una URL específica cuando se activa un evento, puedes usar history.push() proporcionado por react-router-dom. Aquí tienes un ejemplo:
import React from'react';
import { useHistory } from'react-router-dom';
function Componente() {
const history = useHistory();
const handleClick = () => {
// Navegar a una URL específica
history.push('/ruta-deseada');
};
return (
<buttononClick={handleClick}>Ir a la página deseada</button>
);
}
exportdefault Componente;
En este ejemplo, history.push('/ruta-deseada') navegará a la URL especificada cuando se haga clic en el botón.
Recuerda que useHistory es un hook proporcionado por react-router-dom que te permite acceder al objeto history y realizar acciones de navegación programática en tu aplicación React.
Interfaces
En TypeScript, las interfaces permiten definir la forma o estructura de un objeto, incluyendo cómo deben ser las propiedades y qué tipos de datos pueden contener. Cuando se usan con funciones, las interfaces pueden definir los tipos de argumentos que las funciones deben recibir, así como el tipo de valor que deben devolver.
Ejemplo Básico: Definir una Interfaz para una Función
Supongamos que queremos definir una función que toma dos números y devuelve su suma. Podemos usar una interfaz para definir la estructura de esa función.
// Definimos una interfaz que describe una función
interface Suma {
(a?: number, b?: number): number;
}
// Implementamos la función basada en la interfaz
const sumar: Suma = (x, y) => {
return x + y;
};
console.log(sumar(5, 3)); // 8
Explicación del Ejemplo:
Interfaz Suma:
La interfaz Suma describe una función que recibe dos argumentos a y b, ambos de tipo number, y que devuelve un valor de tipo number.
(a: number, b: number): number; es la firma de la función definida por la interfaz.
Implementación de la función sumar:
const sumar: Suma = (x, y) => { ... } es una función que se asigna a la constante sumar, y esta función debe cumplir con la estructura definida por la interfaz Suma.
TypeScript verifica que sumar toma dos números como parámetros y devuelve un número, según lo definido en la interfaz.
Ejemplo Más Complejo: Interfaz con Funciones y Propiedades
Imaginemos un caso en el que queremos definir un objeto que tenga propiedades y también funciones. La interfaz en este caso no solo describe funciones, sino también otras propiedades del objeto.
// Definimos una interfaz para un objeto que tiene propiedades y métodos
interface Calculadora {
nombre: string;
sumar(a: number, b: number): number;
restar(a: number, b: number): number;
}
// Creamos un objeto que implemente la interfaz Calculadora
La interfaz Calculadora define un contrato para cualquier objeto que quiera implementarla. Este objeto debe tener una propiedad nombre de tipo string y dos métodos: sumar y restar, ambos con dos parámetros de tipo number que devuelven un number.
Objeto miCalculadora:
El objeto miCalculadora cumple con la interfaz Calculadora. Tiene una propiedad nombre y las funciones sumar y restar implementadas de acuerdo a la definición de la interfaz.
Ventajas de Usar Interfaces en TypeScript con Funciones:
Seguridad de Tipos: TypeScript verifica que las funciones y objetos cumplen con las interfaces definidas, evitando errores comunes de tipo.
Documentación: Las interfaces actúan como documentación para otros desarrolladores, indicando claramente qué tipos de datos espera una función o un objeto.
Flexibilidad: Puedes definir contratos complejos que deben ser cumplidos por las funciones y objetos, haciendo que el código sea más robusto y fácil de mantener.
Este enfoque es muy útil cuando trabajas con componentes en React, donde puedes definir interfaces para las props y asegurarte de que cada componente reciba lo que necesita. ¿Te gustaría ver un ejemplo de cómo usar interfaces con funciones en un contexto de React?