0% encontró este documento útil (0 votos)
13 vistas163 páginas

React Completo

React es una librería de JavaScript desarrollada por Facebook para crear interfaces de usuario, enfocándose en la reutilización de componentes en aplicaciones medianas y grandes. Para comenzar a desarrollar con React, se requiere instalar Node.js y utilizar la herramienta create-react-app para generar la estructura del proyecto. El formato JSX permite escribir componentes que se compilan a JavaScript puro, facilitando la creación de interfaces visuales dinámicas.

Cargado por

allan milla
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 PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
13 vistas163 páginas

React Completo

React es una librería de JavaScript desarrollada por Facebook para crear interfaces de usuario, enfocándose en la reutilización de componentes en aplicaciones medianas y grandes. Para comenzar a desarrollar con React, se requiere instalar Node.js y utilizar la herramienta create-react-app para generar la estructura del proyecto. El formato JSX permite escribir componentes que se compilan a JavaScript puro, facilitando la creación de interfaces visuales dinámicas.

Cargado por

allan milla
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 PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 163

24/4/23, 14:57 ¿Qué es React?

1 - ¿Qué es React?

React (https://reactjs.org/) es una librería de Javascript para la generación de interfaces visuales.

Está pensado para generar componentes y ser reutilizadas en proyectos medianos y grandes.

Sus principales competidores son Vue (https://vuejs.org/) (proyecto iniciado por Evan You en 2014) y Angular
(https://angular.io/) (proyecto de Goolge que data de 2010)

React es un proyecto desarrollado por la empresa Facebook y tiene sus inicios en el año 2013

React nos facilita la implementación de páginas SPA (Single-Page Application) o aplicaciones de página única en un sitio
web, este tipo de aplicaciones tiene por objetivo dar al visitante una experiencia más parecida a las aplicaciones de
escritorio.

Utiliza la metodología de programación orientada a componentes en forma similar a sus competidores Vue y Angular.

Para desarrollar en forma efectiva una aplicación debemos instalar al menos dos herramientas básicas:

Node.js

create-react-app

Instalación de Node.js
La primer herramienta a instalar será Node.js, esto debido a que gran cantidad de programas para el desarrollo en React.js
están implementadas en Node.

Debemos Descargar e instalar la última versión estable de Node.js (https://nodejs.org/en/):

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=1&codigo=1&inicio=0 1/3
24/4/23, 14:57 ¿Qué es React?

Una vez instalado Node.js desde la línea de comandos del mismo podemos comprobar su correcto funcionamiento
averiguando su versión:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=1&codigo=1&inicio=0 2/3
24/4/23, 14:57 ¿Qué es React?

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=1&codigo=1&inicio=0 3/3
24/4/23, 14:57 Creación del primer proyecto empleando React

2 - Creación del primer proyecto empleando React

En el concepto anterior presentamos que es React y la instalación de Node.Js, veamos ahora los pasos que debemos dar
para crear el primer proyecto.

La aplicación create-react-app nos automatiza la generación de todos los archivos y carpetas básicas del proyecto y nos
instala Webpack, Babel, EsLint etc. más adelante veremos el objetivo de cada uno de estos programas.

Creación del proyecto.


Debemos abrir la consola de comandos de Node y proceder a llamar al programa npx create-react-app pasando como
parámetro el nombre del proyecto a crear:

npx create-react-app proyecto001

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=2&codigo=2&inicio=0 1/11
24/4/23, 14:57 Creación del primer proyecto empleando React

'npx' es una aplicación que descarga la última versión del programa 'create-react-app', dicha aplicación es la que crea el
esqueleto de nuestra aplicación mínima en React.

Requiere varios segundos para que se creen las carpetas, archivos básicos y descarguen los programas que necesita luego
la aplicación:

Luego de esto podemos probar la aplicación mínima sin hacer cambios descendiendo desde la línea de comandos a la
carpeta 'proyecto001' y ejecutando npm start:

cd proyecto001
npm start

Al cabo de unos segundos se abre el navegador y aparece la aplicación funcionando:


https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=2&codigo=2&inicio=0 2/11
24/4/23, 14:57 Creación del primer proyecto empleando React

Antes de analizar las carpetas y archivos generados probemos de hacer unos cambios mínimos en el archivo 'App.js' que
tiene actualmente el contenido:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=2&codigo=2&inicio=0 3/11
24/4/23, 14:57 Creación del primer proyecto empleando React

import logo from './logo.svg';


import './App.css';

function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=2&codigo=2&inicio=0 4/11
24/4/23, 14:57 Creación del primer proyecto empleando React

export default App;

Disponemos el siguiente contenido:

function App() {
return (
<h1>Hola mundo</h1>
);
}

export default App;

Para hacer los cambios podemos utilizar cualquier editor de texto, yo recomiendo Visual Studio Code
(https://code.visualstudio.com/download)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=2&codigo=2&inicio=0 5/11
24/4/23, 14:57 Creación del primer proyecto empleando React

Luego de grabar el archivo, volvemos a ver el navegador y comprobar que se actualizó en forma automática la pantalla:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=2&codigo=2&inicio=0 6/11
24/4/23, 14:57 Creación del primer proyecto empleando React

Es importante tener en cuenta de NO cerrar la consola de Node.js donde está en ejecución la aplicación (si la cerramos por
error la debemos volver a abrir y ejecutar 'npm start' en la carpeta del proyecto):

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=2&codigo=2&inicio=0 7/11
24/4/23, 14:57 Creación del primer proyecto empleando React

Archivos y carpetas principales


Veremos algunos archivos y carpetas esenciales de todo proyecto:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=2&codigo=2&inicio=0 8/11
24/4/23, 14:57 Creación del primer proyecto empleando React

El archivo 'index.html' que se encuentra en la carpeta 'public' tiene un elemento div donde en forma dinámica y mediante
Javascript se agregaran en su interior los elementos HTML de nuestro programa:

<div id="root"></div>

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=2&codigo=2&inicio=0 9/11
24/4/23, 14:57 Creación del primer proyecto empleando React

El segundo archivo importante es el 'index.js' que se encuentra en la carpeta 'src' del proyecto:

import React from 'react';


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

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

// If you want to start measuring performance in your app, pass a function


// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

En los próximos conceptos comenzaremos con el código de React en este momento solo quiero que veamos como se
relacionan estos archivos. En la llamada al método render del objeto ReactDOM mediante getElementById obtenemos la
referencia del div del otro archivo (index.html) llamado 'root':

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

El método render es el responsable de generar todas las etiquetas HTML en forma dinámica. El primer parámetro del
método render es la referencia de la componente 'App' que se encuentra en el archivo 'App.js':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=2&codigo=2&inicio=0 10/11
24/4/23, 14:57 Creación del primer proyecto empleando React

function App() {
return (
<h1>Hola mundo</h1>
);
}

export default App;

App es una componente funcional (a partir de la versión 16.8 de la librería de React la propuesta por defecto es el empleo
de componentes funcionales en lugar de clases)

Hemos visto los tres archivos que siempre existirán en todo proyecto que desarrollemos con React:

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=2&codigo=2&inicio=0 11/11
24/4/23, 15:18 Formato JSX

3 - Formato JSX

Creamos en el concepto anterior la primer aplicación en React utilizando la aplicación create-react-app y vimos que se
genera un archivo llamado App.js y en su interior se crea por defecto la función 'App':

function App() {
return (
<h1>Hola mundo</h1>
);
}

export default App;

Analizaremos ahora cual es el objetivo del valor retornado por la función App.

Problema
Crear el segundo proyecto escribiendo desde la línea de comandos de Node.js:

npx create-react-app proyecto002

La función App no retorna ni HTML, ni Javascript puro, es un nuevo formato propuesto por los creadores de React que luego
de ser compilado se genera Javascript puro que lo pueden entender los navegadores.

Hay ciertas reglas que debe cumplir el formato JSX (JavaScript XML), presentaremos algunas de ellas en este segundo
ejercicio.

Modifiquemos valor devuelto por la función App:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=3&codigo=3&inicio=0 1/10
24/4/23, 15:18 Formato JSX

import './App.css';

function retornarAleatorio() {
return Math.trunc(Math.random() * 10);
}

function App() {
const siglo = 21
const persona = {
nombre: 'Juan',
edad: 34
}
return (
<div>
<h1>Título nivel 1</h1>
<hr />
<p>Estamos en el siglo {siglo}</p>
<h3>Acceso a un objeto</h3>
<p>{persona.nombre} tiene {persona.edad} años</p>
<h3>Llamada a un método</h3>
<p>Un valor aleatorio llamando a un método.</p>
{retornarAleatorio()}
<h3>Calculo inmediato de expresiones</h3>
3 + 3 = {3 + 3}
</div>
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=3&codigo=3&inicio=0 2/10
24/4/23, 15:18 Formato JSX

);
}

export default App;

La función App tiene por objetivo retornar el elemento JSX que representa la interfaz visual de la componente 'App' (por el
momento desarrollaremos toda nuestra aplicación en una única componente, luego veremos que un programa se
descompone en muchas componentes)

Como vemos dentro del bloque de JSX podemos disponer etiquetas HTML tal como conocemos:

<h1>Título nivel 1</h1>

Una restricción de JSX es que siempre los elementos HTML deben tener su marca de comienzo y fin, y en el caso que solo
tengan una etiqueta que es tanto de comienzo como fin debemos agregar el caracter '/':

<hr />

Si nos olvidamos de agregar la barra de cierre se genera un error cuando tratamos de compilar la aplicación:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=3&codigo=3&inicio=0 3/10
24/4/23, 15:18 Formato JSX

Dentro del bloque JSX podemos acceder a variables o constantes indicando entre llaves dicha variable o constante:

<p>Estamos en el siglo {siglo}</p>

Luego cuando se compila en lugar de la expresión se muestra el contenido de la variable o constante:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=3&codigo=3&inicio=0 4/10
24/4/23, 15:18 Formato JSX

En forma similar podemos disponer expresiones para acceder a propiedades de un objeto previamente definido:

<p>{persona.nombre} tiene {persona.edad} años</p>

Otra posibilidad en una expresión es hacer la llamada a otras funciones:

{retornarAleatorio()}

Podemos inclusive disponer una operación que será ejecutada previo a su visualización:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=3&codigo=3&inicio=0 5/10
24/4/23, 15:18 Formato JSX

3 + 3 = {3 + 3}

Otras restricciones que tiene el formato JSX


Se recomienda dividir el JSX en varias líneas para facilitar la lectura, también recomiendan envolverlo entre paréntesis para
evitar los inconvenientes de la inserción automática de punto y coma.

Para definir valores a las propiedades de un elementos HTML mediante expresiones no debemos disponer las comillas. Por
ejemplo modifique el método render() y pruebe esto:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=3&codigo=3&inicio=0 6/10
24/4/23, 15:18 Formato JSX

import './App.css';

function retornarAleatorio() {
return Math.trunc(Math.random() * 10);
}

function App() {
const buscadores = ['http://www.google.com',
'http://www.bing.com',
'http://www.yahoo.com'];
return (
<div>
<a href={buscadores[0]}>Google</a><br />
<a href={buscadores[1]}>Bing</a><br />
<a href={buscadores[2]}>Yahoo</a><br />
</div>
);
}

export default App;

No deben ir las comillas en la asignación de la propiedad href si el valor se extrae de una expresión:

<a href={buscadores[0]}>Google</a><br />

Si queremos darle el valor directamente si se requieren las comillas:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=3&codigo=3&inicio=0 7/10
24/4/23, 15:18 Formato JSX

<a href="http://www.google.com">Google</a><br />

Podemos plantear funciones que retornen trozos de JSX que luego se agregan al que retorna la función App, probar de
modificar nuevamente el problema con:

import './App.css';

function mostrarTitulo(tit) {
return (<h1>
{tit}
</h1>);
}

function App() {
return (
<div>
{mostrarTitulo('Hola Mundo')}
{mostrarTitulo('Fin')}
</div>
);
}

export default App;

Una restricción del JSX es que siempre debe retornar un elemento HTML que puede tener en su interior otros elementos
anidados, pero nunca dos elementos HTML hermanos, esto genera un error:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=3&codigo=3&inicio=0 8/10
24/4/23, 15:18 Formato JSX

function App() {
return (
<div>
<h1>Titulo 1</h1>
</div>
<div>
<h1>Titulo 2</h1>
</div>
);
}

Debemos disponer obligatoriamente solo un elemento div que envuelva todo:

function App() {
return (
<div>
<div>
<h1>Titulo 1</h1>
</div>
<div>
<h1>Titulo 2</h1>
</div>
</div>
);
}

Se puede utilizar otros elementos HTML para envolver todo el JSX como por ejemplo 'span', 'section' o cualquier otro,
siempre y cuando no haya elementos hermanos en la raíz (inclusive podemos encerrarlo con etiquetas vacías):

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=3&codigo=3&inicio=0 9/10
24/4/23, 15:18 Formato JSX

function App() {
return (
<><div>
<h1>Titulo 1</h1>
</div><div>
<h1>Titulo 2</h1>
</div>
</>
);

Importante
Otra cosa muy importante que hay que tener en cuenta que los nombres de las propiedades de los elementos HTML
cambian en varias situaciones:

Debemos utilizar la palabra 'className' en lugar de class (debido a que class es una palabra clave de Javascript):

<h1 className="recuadro">Titulo 1</h1>

Si el nombre de la propiedad está formada por más de una palabra luego el primer caracter a partir de la segunda palabra
debe ir en mayúsculas:

<input type="text" tabIndex="1" />

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=3&codigo=3&inicio=0 10/10
24/4/23, 15:28 Captura de eventos

4 - Captura de eventos

Los nombres de eventos en React comienzan con "on" y luego el primer caracter de cada palabra en mayúsculas:

onClick
onDoubleClick
onMouseEnter
onMouseLeave
onMouseMove
onKeyPress
onKetUp
onSubmit
etc.

Problema
Disponer dos controles de formulario HTML input="number" y un botón. Al presionar el botón mostrar en un alert su suma.

Crear con la aplicación create-react-app el proyecto003.

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=4&codigo=4&inicio=0 1/4
24/4/23, 15:28 Captura de eventos

import logo from './logo.svg';


import './App.css';

function App() {
return (
<div>
<form onSubmit={presion}>
<p>Ingrese primer valor:
<input type="number" name="valor1" />
</p>
<p>Ingrese segundo valor:
<input type="number" name="valor2" />
</p>
<p>
<input type="submit" value="Sumar" />
</p>
</form>
</div>
);
}

function presion(e) {
e.preventDefault();
const v1=parseInt(e.target.valor1.value, 10);
const v2=parseInt(e.target.valor2.value, 10);
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=4&codigo=4&inicio=0 2/4
24/4/23, 15:28 Captura de eventos

const suma=v1+v2;
alert('La suma es:'+suma);
}

export default App;

Cuando ejecutamos la aplicación luego de cargar los dos enteros y presionar el botón 'submit' tenemos:

Lo más importante en este problema es ver como enlazamos el evento onSubmit con la función presion.

En la función App inicializamos el evento onSubmit con la referencia de la función 'presion':

<form onSubmit={presion}>

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=4&codigo=4&inicio=0 3/4
24/4/23, 15:28 Captura de eventos

La función presion propiamente dicha primero detiene el envío de datos al servidor llamando a preventDefault, luego
recupera los dos valores ingresados por teclado y muestra su suma:

function presion(e) {
e.preventDefault();
const v1=parseInt(e.target.valor1.value, 10);
const v2=parseInt(e.target.valor2.value, 10);
const suma=v1+v2;
alert('La suma es:'+suma);
}

El objetivo de este concepto es ver un poco la sintaxis como enlazar un evento que dispara un control HTML y el método
que lo captura.

En conceptos futuros analizaremos cada uno de los controles de formulario y como procesarlos.

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=4&codigo=4&inicio=0 4/4
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

5 - Variables de estado de una componente mediante


Hook (función useState)

Un Hook de estado es una función especial que nos permite conectarnos a las funciones de la librería de React.

Una componente en React si necesita almacenar valores que luego en forma dinámica se actualizarán en pantalla, lo
podemos resolver mediante Hook de estado. Por ejemplo un contador de productos seleccionados, un contador de
segundos que se muestra en pantalla, la hora etc.

Debemos importar la función 'useState' si queremos administrar Hook de estados:

import React, { useState } from 'react';

Problema
Crear un nuevo proyecto llamado: proyecto004.
Definir en la interfaz visual un botón que cada vez que se presione se actualice en pantalla un número aleatorio entre 0 y 9.

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 1/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

import { useState } from "react";

function App() {

function generarAleatorio() {
const v = Math.trunc(Math.random() * 10);
setNumero(v)
}

const [numero, setNumero] = useState(0);

return (
<div>
<p>Número aleatorio: {numero}</p>
<button onClick={generarAleatorio}>Generar número aleatorio</button>
</div>
);
}

export default App;

Llamamos a la función useState y definimos el valor inicial, en nuestro caso el valor entero cero, la función retorna un
arreglo con dos valores que se almacenan en numero y setNumero (podemos definir cualquier nombre para estas dos
variables):

const [numero, setNumero] = useState(0);

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 2/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

La desestructuración de los dos elementos del arreglo que retorna useState es una característica del lenguaje Javascript
(ES6)

En la posicion cero del arreglo nos retorna la variable de estado y la posicion uno nos retorna una funcion que nos sirve para
actualizar la variable de estado y las almacenamos en 'numero' y 'setNumero'.

Cuando queremos cambiar el valor de la variable de estado llamamos a la función setNumero:

function generarAleatorio() {
const v = Math.trunc(Math.random() * 10);
setNumero(v)
}

Y cuando queremos rescatar su valor accedemos directamente a la variable de estado 'numero':

<p>Número aleatorio: {numero}</p>

Luego cuando se presiona el botón se dispara el evento generarAleatorio:

<button onClick={generarAleatorio}>Generar número aleatorio</button>

Cuando se llama a la función 'setNumero' modificamos la variable de estado, con esto la librería React se encarga de
ejecutar nuevamente la graficación de la componente pero solo actualizando los estados cambiados y sin tener que
redibujar la página completa (tener en cuenta que se ejectua nuevamente la función App, pero no se crea e inicializa
nuevamente la variable de estado con cero. La documentación de React informa que se definió el nombre de la función
'useState' en lugar de 'createState' debido a que solo la primera vez que se llama a 'useState' se crea la variable de estado
e inicializa en nuestro ejemplo con cero)

Tenemos como resultado en el navegador:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 3/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

Problema
Modificar el problema anterior para que se muestren 5 valores aleatorios. Almacenar los 5 valores en un vector y éste en la
variable de estado.

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 4/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

import { useState } from "react";

function App() {

function generarAleatorios() {
const vec = new Array(5)
for (let x = 0; x < vec.length; x++)
vec[x] = Math.trunc(Math.random() * 10)
setNumeros(vec)
}

const [numeros, setNumeros] = useState([0, 0, 0, 0, 0]);

return (
<div>
<p>Números aleatorios:</p>
{numeros.map(num => (<p>{num}</p>))}
<button onClick={generarAleatorios}>Generar números aleatorios</button>
</div>
);
}

export default App;

A la función useState podemos pasar tanto tipos de datos primitivos como vectores:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 5/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

const [numeros, setNumeros] = useState([0,0,0,0,0]);

En la función generarAleatorios() procedemos a crear un vector de 5 elementos y guardar los 5 valores aleatorios.
Seguidamente llamamos a la función 'setNumeros':

function generarAleatorios() {
const vec=new Array(5)
for(let x=0; x<vec.length; x++)
vec[x]=Math.trunc(Math.random()*10)
setNumeros(vec)
}

Para mostrar todos los elemento del vector llamamos al método map de la clase Array y le pasamos una función flecha que
retorna para cada elemento del vector un valor encerrado entre las marcas 'p':

{numeros.map(num => (<p>{num}</p>))}

Problema
Crear un nuevo proyecto con la herramienta create-react-app llamado proyecto005.
Almacenar en el estado de la componente el siguiente vector con artículos:

[{
codigo: 1,
descripcion: 'papas',
precio: 12.52
},{
codigo: 2,
descripcion: 'naranjas',
precio: 21
},{
codigo: 3,
descripcion: 'peras',
precio: 18.20
}]

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 6/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

Mostrar en una tabla HTML dichos datos. Cuando se presione un botón borrar el último elemento de la tabla.

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 7/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

import { useState } from "react";

function App() {

function eliminarUltimaFila() {
if (articulos.length > 0) {
const temp=Array.from(articulos)
temp.pop()
setArticulos(temp)
}
}

const [articulos, setArticulos] = useState([{


codigo: 1,
descripcion: 'papas',
precio: 12.52
}, {
codigo: 2,
descripcion: 'naranjas',
precio: 21
}, {
codigo: 3,
descripcion: 'peras',
precio: 18.20
}]);
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 8/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

return (
<div>
<table border="1">
<thead><tr><th>Código</th><th>Descripción</th><th>Precio</th></tr></t
<tbody>
{articulos.map(art => {
return (
<tr key={art.codigo}>
<td>
{art.codigo}
</td>
<td>
{art.descripcion}
</td>
<td>
{art.precio}
</td>
</tr>
)
})}
</tbody>
</table>
<button onClick={eliminarUltimaFila}>Eliminar última fila</button>
</div>

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 9/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

);
}

export default App;

Llamamos a la función useState para crear la variable de estado y le pasamos el arreglo de objetos

const [articulos, setArticulos] = useState([{


codigo: 1,
descripcion: 'papas',
precio: 12.52
}, {
codigo: 2,
descripcion: 'naranjas',
precio: 21
}, {
codigo: 3,
descripcion: 'peras',
precio: 18.20
}]);

Para mostrar los datos del vector nuevamente empleamos la llamada al método 'map' y le pasamos una función anónima.
Dentro de la función anónima generamos cada fila de la tabla con los datos de un producto:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 10/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

<table border="1">
<thead><tr><th>Código</th><th>Descripción</th><th>Precio</th></tr></thead>
<tbody>
{articulos.map(art => {
return (
<tr key={art.codigo}>
<td>
{art.codigo}
</td>
<td>
{art.descripcion}
</td>
<td>
{art.precio}
</td>
</tr>
)
})}
</tbody>
</table>

Como podemos comprobar la fila de títulos de la tabla la hacemos previo a llamar a map.

Cuando se presiona el botón llamamos a la función 'eliminarUltimaFila. Primero comprobamos si el vector tiene elementos
accediendo al atributo 'length', en caso afirmativo procedemos a crear una copia del vector original llamando al método from
y almacenando en una variable temporal el nuevo vector, luego eliminamos el último elemento llamando al método pop y
finalmente actualizamos la variable de estado llamando a la función 'setArticulos' (hay que tener en cuenta que debemos
crear siempre un nuevo vector con la copia del original y pasar dicho valor):

function eliminarUltimaFila() {
if (articulos.length > 0) {
const temp=Array.from(articulos)
temp.pop()
setArticulos(temp)
}
}

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 11/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

Problema
Modificar el ejercicio anterior para que aparezca un botón en cada fila de la tabla y permita borrar dicho artículo.

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 12/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

import { useState } from "react";

function App() {

function borrar(cod) {
const temp = articulos.filter((art)=>art.codigo !== cod);
setArticulos(temp)
}

const [articulos, setArticulos] = useState([{


codigo: 1,
descripcion: 'papas',
precio: 12.52
}, {
codigo: 2,
descripcion: 'naranjas',
precio: 21
}, {
codigo: 3,
descripcion: 'peras',
precio: 18.20
}]);

return (
<div>
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 13/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

<table border="1">
<thead><tr><th>Código</th><th>Descripción</th><th>Precio</th><th>Borr
<tbody>
{articulos.map(art => {
return (
<tr key={art.codigo}>
<td>
{art.codigo}
</td>
<td>
{art.descripcion}
</td>
<td>
{art.precio}
</td>
<td>
<button onClick={() => borrar(art.codigo)}>Borrar</button>
</td>
</tr>
)
})}
</tbody>
</table>
</div>
);

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 14/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

export default App;

Cuando generamos ahora la tabla en la última celda debemos disponer un botón que llame a una función y le pase como
parámetro el código de artículo a borrar:

<button onClick={() => borrar(art.codigo)}>Borrar</button>

Cuando llamamos a una función debemos plantear una función anónima que se le asigna al evento 'onClick'.

La función 'borrar' recibe como parámetro el codigo de artículo a borrar:

function borrar(cod) {
const temp = articulos.filter((art)=>art.codigo !== cod);
setArticulos(temp)
}

Para borrar un determinado elemento del vector utilizamos el método filter que genera otro vector con todas las
componentes que cumplen la condición que le pasamos en la función anónima.

Finalmente actualizamos el estado para que se redibuje la página.

Tenemos como resultado:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 15/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

Acotaciones
Las variables de estado pueden almacenar datos de tipo:

String.

Boolean

Number

Array

Object

Undefined

Los valores iniciales del estado se ejecutan solo una vez y es cuando se carga la componente.

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 16/17
24/4/23, 15:29 Variables de estado de una componente mediante Hook (función useState)

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=5&codigo=5&inicio=0 17/17
25/4/23, 08:54 Componentes

6 - Componentes

Las componentes son una característica fundamental de React. Nos permiten dividir la aplicación en trozos de nuestra
interfaz visual con objetivos bien definidos: 'menú de opciones', 'formulario de búsqueda', 'ventanas de mensajes', 'tablas de
datos' etc.

La división de nuestra aplicación en componentes nos ayudan a reutilizar dicho código en proyectos futuros.

Hasta ahora cada proyecto que hemos desarrollado ha implementado una sola componente funcional llamada 'App'
(hacemos referencia a que se trata de una componente funcional, ya que versiones antiguas de React proponían por
defecto una componente de clase)

Problema
Crear un nuevo proyecto con la herramienta create-react-app llamado proyecto006

Confeccionar una aplicación que muestre tres dados.

Plantear una componente funcional llamada 'Dado' que tenga una propiedad llamada 'valor' a la cual le llega el dato a
mostrar.
Nuestra componente principal seguirá siendo 'App' y dentro de la misma definiremos 3 componentes de tipo 'Dado':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 1/11
25/4/23, 08:54 Componentes

Veamos todos los pasos que debemos dar para poder implementar este proyecto empleando 2 componentes:

Primero creamos en la carpeta src dos archivos llamados 'Dado.js' y 'Dado.css'

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 2/11
25/4/23, 08:54 Componentes

Codificamos la componente 'Dado' en el archivo 'Dado.js':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 3/11
25/4/23, 08:54 Componentes

import './Dado.css'

function Dado(props) {
return (
<div className="dado-recuadro">{props.valor}</div>
);
}

export default Dado

Mostramos el dato almacenado en la propiedad 'valor' que llegará desde la componente 'App' mediante el parámetro
props:

<div className="dado-recuadro">{props.valor}</div>

Utilizamos estilos para que el dado aparezca mejor en pantalla. Los estilos los guardamos en el archivo 'Dado.css' y lo
debemos importar para utilizarlo en el div:

import './Dado.css'

Como importaremos la clase 'Dado' luego en la clase 'App' debemos exportarla:

export default Dado

También codificamos el archivo 'Dado.css':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 4/11
25/4/23, 08:54 Componentes

.dado-recuadro {
display: flex;
width: 2rem;
height: 2rem;
background-color: black;
color: white;
justify-content: center;
align-items: center;
margin: 1rem;
border-radius: 4px;
}

Ahora codificamos la función 'App':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 5/11
25/4/23, 08:54 Componentes

import Dado from "./Dado";

function App() {
const valor1 = Math.trunc(Math.random()*6)+1
const valor2 = Math.trunc(Math.random()*6)+1
const valor3 = Math.trunc(Math.random()*6)+1
return (
<div>
<Dado valor={valor1} />
<Dado valor={valor2} />
<Dado valor={valor3} />
</div>
);
}

export default App;

Lo primero que debemos hacer para poder utilizar la componente Dado es importarla:

import Dado from './Dado';

Lo nuevo es que en el bloque JSX definimos tres etiquetas Dado y pasamos la propiedad valor con distintos valores
aleatorios previamente generados:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 6/11
25/4/23, 08:54 Componentes

const valor1 = Math.trunc(Math.random()*6)+1


const valor2 = Math.trunc(Math.random()*6)+1
const valor3 = Math.trunc(Math.random()*6)+1
return (
<div>
<Dado valor={valor1} />
<Dado valor={valor2} />
<Dado valor={valor3} />
</div>
);

Podemos ver la potencia que puede tener la declaración de componentes y luego crear tantas como necesitemos.

Si ejecutamos ahora la aplicación desde la línea de comandos de Node.js 'npm start' tenemos como resultado:

Problema
En el problema anterior si necesitamos sortear otros tres dados estamos obligados a recargar la página. Modificaremos la
aplicación y agregaremos un botón para que cada vez que se presione nos actualice únicamente los valores de los tres
dados sin tener que recargar en forma completa la página.
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 7/11
25/4/23, 08:54 Componentes

Solo debemos efectuar cambios en la función App:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 8/11
25/4/23, 08:54 Componentes

import Dado from "./Dado";


import { useState } from "react";

function App() {

function generarValor() {
return Math.trunc(Math.random() * 6) + 1
}

function tirar() {
setNumero1(generarValor())
setNumero2(generarValor())
setNumero3(generarValor())
}

const [numero1, setNumero1] = useState(generarValor())


const [numero2, setNumero2] = useState(generarValor())
const [numero3, setNumero3] = useState(generarValor())
return (
<div>
<Dado valor={numero1} />
<Dado valor={numero2} />
<Dado valor={numero3} />
<button onClick={tirar}>Tirar</button>
</div>
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 9/11
25/4/23, 08:54 Componentes

);
}

export default App;

Guardamos el estado de tres valores aleatorios en numero1, numero2 y numero3. Además recordemos que inicializamos
tres variables con las funciones que se llamarán cuando necesitemos cambiar los valores de las variables de estado:

const [numero1, setNumero1] = useState(generarValor())


const [numero2, setNumero2] = useState(generarValor())
const [numero3, setNumero3] = useState(generarValor())

En el bloque JSX recuperamos el 'estado' de los tres valores a pasar a cada componente 'Dado':

return (
<div>
<Dado valor={numero1} />
<Dado valor={numero2} />
<Dado valor={numero3} />
<button onClick={tirar}>Tirar</button>
</div>
);

La función tirar() modifica el 'estado' llamando a la función setNumero de cada variable de estado, esto hace que se
actualicen en pantalla los nuevos valores de cada dado sin tener que recargar toda la página:

function tirar() {
setNumero1(generarValor())
setNumero2(generarValor())
setNumero3(generarValor())
}

En el navegador tenemos como resultado:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 10/11
25/4/23, 08:54 Componentes

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 11/11
25/4/23, 09:03 Componentes: propiedades

7 - Componentes: propiedades

El elemento fundamental que tenemos para comunicarnos con una componente son las propiedades. Mediante las
propiedades podemos enviar datos a la componente para que los muestre.

En el concepto anterior vimos como pasar un valor entero a la componente Dado mediante la sintaxis (empleando una
variable de estado con el API de Hook de React):

<Dado valor={valor1} />

Luego dentro de la componente 'Dado' accedemos al valor pasado mediante el parametro'props':

function Dado(props) {
return (
<div className="dado-recuadro">{props.valor}</div>
);
}

Podemos pasar cualquier tipo de datos a una componente, no solo tipos primitivos como enteros, reales, string.

Problema
Confeccionar una aplicación que permita ingresar por teclado dos enteros y nos muestre la suma. Agregar a una lista todas
las operaciones ejecutadas hasta este momento.

Crear un nuevo proyecto con la herramienta create-react-app llamado proyecto007

Primero creamos el archivo 'ListadoResultados.js' en la carpeta 'src' donde definimos la componente con el mismo nombre:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=7&codigo=7&inicio=0 1/7
25/4/23, 09:03 Componentes: propiedades

function ListadoResultados(props) {
return (
<ul>
{props.resultados.map((elemento) =>
<li>La suma de {elemento.valor1} y {elemento.valor2} es {elemento.res
)}
</ul>
);
}

export default ListadoResultados;

El parámetro 'props' dispone de una propiedad llamada 'resultados' que llegará desde la componente 'App'. La misma es un
vector con componentes de tipo objeto que almacenan los dos valores y el resultado de su suma.

Podemos imaginar que llega algo similar a esto:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=7&codigo=7&inicio=0 2/7
25/4/23, 09:03 Componentes: propiedades

[
{
valor1: 10,
valor2: 12,
resultado: 22
},
{
valor1: 5,
valor2: 20,
resultado: 25
},
{
valor1: 1,
valor2: 1,
resultado: 2
}
]

La componente App es:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=7&codigo=7&inicio=0 3/7
25/4/23, 09:03 Componentes: propiedades

import ListadoResultados from "./ListadoResultados";


import { useState } from "react";

function App() {

const [operaciones, setOperacion] = useState([])

function sumar(event) {
event.preventDefault();
const v1 = parseInt(event.target.valor1.value, 10)
const v2 = parseInt(event.target.valor2.value, 10)
const suma = v1 + v2
const nuevo = {
resultado: suma,
valor1: v1,
valor2: v2
}
setOperacion([nuevo, ...operaciones])
event.target.valor1.value = ''
event.target.valor2.value = ''
}

return (
<div>
<form onSubmit={sumar}>
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=7&codigo=7&inicio=0 4/7
25/4/23, 09:03 Componentes: propiedades

<p>Ingrese primer valor:<input type="text" name="valor1" /></p>


<p>Ingrese segundo valor:<input type="text" name="valor2" /></p>
<input type="submit" value="Sumar" />
</form>
<ListadoResultados resultados={operaciones} />
</div>
);
}

export default App;

Importamos el archivo que contiene la componente funcional ListadoResultados:

import ListadoResultados from "./ListadoResultados";

En la función App definimos la variable de estado donde almacenaremos un arreglo con las distintas operaciones
efectuadas:

const [operaciones, setOperacion] = useState([])

El el bloque JSX además del formulario de entrada de datos propiamente dicho definimos un elemento de tipo
'ListadoResultados' y le pasamos la propiedad 'resultado' con el valor almacenado en la variable de estado 'operaciones':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=7&codigo=7&inicio=0 5/7
25/4/23, 09:03 Componentes: propiedades

return (
<div>
<form onSubmit={sumar}>
<p>Ingrese primer valor:<input type="text" name="valor1" /></p>
<p>Ingrese segundo valor:<input type="text" name="valor2" /></p>
<input type="submit" value="Sumar" />
</form>
<ListadoResultados resultados={operaciones} />
</div>
);

Cada vez que se presiona el botón sumar se ejecuta la función 'sumar' donde agregamos al estado un nuevo elemento al
principio del vector, esto hará que se actualice la lista de resultados en la página sin tener que recargarla:

function sumar(event) {
event.preventDefault();
const v1 = parseInt(event.target.valor1.value, 10)
const v2 = parseInt(event.target.valor2.value, 10)
const suma = v1 + v2
const nuevo = {
resultado: suma,
valor1: v1,
valor2: v2
}
setOperacion([nuevo, ...operaciones])
event.target.valor1.value = ''
event.target.valor2.value = ''
}

Para actualizar el estado en la variable 'operaciones' de manera correcta, necesitamos pasar otro arreglo completo.
Utilizamos el operador spread para descomponer el vector actual y agregar como primer elemento la nueva operación:

setOperacion([nuevo, ...operaciones])

Si queremos agregar la operación al final del vector luego podemos implementar la siguiente sintaxis:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=7&codigo=7&inicio=0 6/7
25/4/23, 09:03 Componentes: propiedades

setOperacion([...operaciones, nuevo])

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=7&codigo=7&inicio=0 7/7
25/4/23, 09:07 Componentes: eventos generados por una componente

8 - Componentes: eventos generados por una


componente

Una aplicación consta de una componente principal (utilizando la herramienta create-react-app se llama App), en esta
definimos objetos de otras componentes y así sucesivamente cada componente puede estar construida en base a otras
componentes.

Veremos ahora que una componente puede emitir un evento para informar a la componente padre un suceso.

Problema
Modificaremos el proyecto del concepto anterior para implementar el formulario de entrada de datos en otra componente
llamada 'FormularioNumeros'. Las componentes que ahora tendrá la aplicación son:

Debemos crear el archivo 'FormularioNumeros.js' en la carpeta 'src' con el siguiente contenido:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=8&codigo=8&inicio=0 1/5
25/4/23, 09:07 Componentes: eventos generados por una componente

function FormularioNumeros(props) {
return (
<form onSubmit={props.onSumar}>
<p>Ingrese primer valor:<input type="text" name="valor1" /></p>
<p>Ingrese segundo valor:<input type="text" name="valor2" /></p>
<input type="submit" value="Sumar" />
</form>
);
}

export default FormularioNumeros;

En el evento onSubmit le pasaremos la referencia a una función que llega como una propiedad en el parámetro 'props' y lo
llama en la componente padre con el nombre 'onSumar:

<FormularioNumeros onSumar={sumar} />

Ahora el código de la componente 'App' queda con la siguiente sintaxis:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=8&codigo=8&inicio=0 2/5
25/4/23, 09:07 Componentes: eventos generados por una componente

import ListadoResultados from "./ListadoResultados";


import FormularioNumeros from "./FormularioNumeros";
import { useState } from "react";

function App() {

const [operaciones, setOperacion] = useState([])

function sumar(event) {
event.preventDefault();
const v1 = parseInt(event.target.valor1.value, 10)
const v2 = parseInt(event.target.valor2.value, 10)
const suma = v1 + v2
const nuevo = {
resultado: suma,
valor1: v1,
valor2: v2
}
setOperacion([nuevo, ...operaciones])
event.target.valor1.value = ''
event.target.valor2.value = ''
}

return (
<div>
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=8&codigo=8&inicio=0 3/5
25/4/23, 09:07 Componentes: eventos generados por una componente

<FormularioNumeros onSumar={sumar} />


<ListadoResultados resultados={operaciones} />
</div>
);
}

export default App;

Debemos importar primero los dos archivos que contienen las componentes:

import ListadoResultados from "./ListadoResultados";


import FormularioNumeros from "./FormularioNumeros";

El bloque JSX ahora queda muy simple, hemos inicializado la propiedad 'onSumar' con la referencia de la función 'sumar':

return (
<div>
<FormularioNumeros onSumar={sumar} />
<ListadoResultados resultados={operaciones} />
</div>
);

Como vemos la función 'sumar' se ejecuta cuando la componente FormularioNumeros lo requiera.

Finalmente el archivo 'ListadoResultados' no varía con respecto al problema anterior:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=8&codigo=8&inicio=0 4/5
25/4/23, 09:07 Componentes: eventos generados por una componente

function ListadoResultados(props) {
return (
<ul>
{props.resultados.map((elemento) =>
<li>La suma de {elemento.valor1} y {elemento.valor2} es {elemento.res
)}
</ul>
);
}

export default ListadoResultados;

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=8&codigo=8&inicio=0 5/5
25/4/23, 09:36 Hook de efecto (función useEffect)

9 - Hook de efecto (función useEffect)

Vimos en un concepto anterior los hook más utilizados que son los de variables de estado, ahora en orden de uso
presentaremos los hook de efectos.

Recordemos que los hook solo pueden ser utilizados cuando implementamos componentes funcionales, que es la
metodología más actual y propuesta por los creadores de la librería React.

El Hook de efecto permite llevar a cabo efectos secundarios en componentes funcionales, ejemplos de estos efectos son:

Actualizaciones manuales del DOM.

Suscribir y desuscribir a eventos (ej. addEventListener, removeListener)

Peticiones de datos a un servidor (ej. API fetch)

La sintaxis básica la podemos ver en el siguiente código:

import { useEffect } from "react";

function App() {

useEffect(() => console.log("ejecución de useEffect"))

return (
<div>
Hola Mundo
</div>
);
}

export default App

Debemos importar la función:


https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=9&codigo=9&inicio=0 1/11
25/4/23, 09:36 Hook de efecto (función useEffect)

import { useEffect } from "react";

Y en su sintaxis más sencilla pasamos a la función useEffect una función flecha:

useEffect(() => console.log("ejecución de useEffect"))

Sintaxis de la función useEffect


La función useEffect tiene dos parámetros: el primero una función y el segundo un array cuyos valores serán variables
de las que depende nuestro algoritmo que implementa la función que le pasamos (este arreglo es opcional como
vemos en el ejemplo codificado)

La función useEffect se ejecuta en cada renderizado, inclusive en el primero.

Podemos llamar a la función useEffect más de una vez y crear varios hook de efecto.

Está diseñado para que si la función que pasamos por parámetro retorna otra función, React va a ejecutar dicha
función cuando se desmonte el componente del DOM (normalmente en esta función liberamos recursos como
desuscribirse a eventos)

Problema 1
Actualizar en tiempo real el título de la página con los caracteres ingresados en un control input. Para esto debemos acceder
directamente al DOM.

Crear con la aplicación create-react-app el proyecto008.

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=9&codigo=9&inicio=0 2/11
25/4/23, 09:36 Hook de efecto (función useEffect)

import { useState, useEffect } from 'react';

function App() {

const [texto, setTexto] = useState("")

useEffect(() => {document.title = texto}, [texto])

function cambiar(e) {
setTexto(e.target.value)
}

return (
<div>
<p><input type="text" onChange={cambiar} /></p>
<p>{texto}</p>
</div>
);
}

export default App;

Cada vez que escribimos un caracter en el control 'input' se actualiza automáticamente la página con la variable de estado
'texto' y también se ejecuta el hook donde se accede al título de la página mediante 'document':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=9&codigo=9&inicio=0 3/11
25/4/23, 09:36 Hook de efecto (función useEffect)

Importamos las dos funciones que necesitamos para crear un hook de variable de estado y un hook de efecto:

import { useState, useEffect } from 'react';

Llamamos a la función useEffect y le pasamos la función anónima donde actualizamos el título de la página con el valor
almacenado en la variable de estado 'dato' (para que la aplicación sea más eficiente pasamos un segundo parámetro a la
función useEffect con un vector que contiene la variable de estado):

useEffect(() => {document.title = texto}, [texto])

Si pasamos un vector vacío como segundo parámetro, luego no se actualizará el título de la página (si en algún caso
queremos que se ejecute el hook una única vez indistintamente la cantidad de veces que se renderize la componente puede
tener sentido pasar un array vacío, no es el caso actual):

useEffect(() => {document.title = texto}, [])

Definimos un hook de estado con el contenido ingresado en el control input:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=9&codigo=9&inicio=0 4/11
25/4/23, 09:36 Hook de efecto (función useEffect)

const [texto, setTexto] = useState("")

Cada vez que se carga o borra un caracter (es decir hay un cambio) se dispara la función 'cambiar':

<p><input type="text" onChange={cambiar} /></p>

La función 'cambiar' actualiza la variable de estado, lo cual dispara el hook de efecto:

function cambiar(e) {
setTexto(e.target.value)
}

Debajo del control input se muestra también el valor ingresado por teclado:

<p>{texto}</p>

Problema 2
Crear una componente que muestre por pantalla la coordenada donde se encuentra la flecha del mouse. En la componente
principal disponer un botón para desmontar la componente que muestra la coordenada.

La componente 'CoordenadaFlecha' debe registrar la escucha del evento 'mousemove' y desuscribirse de dicho evento
cuando se desmonte la componente.

En principio a medida que movemos la flecha del mouse debe mostrarse la coordenada:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=9&codigo=9&inicio=0 5/11
25/4/23, 09:36 Hook de efecto (función useEffect)

Cuando se presiona el botón se debe desuscribir de la escucha de evento 'mousemove':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=9&codigo=9&inicio=0 6/11
25/4/23, 09:36 Hook de efecto (función useEffect)

Crear con la aplicación create-react-app el proyecto009.

El código fuente de la componente 'CoordenadaFlecha':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=9&codigo=9&inicio=0 7/11
25/4/23, 09:36 Hook de efecto (función useEffect)

import { useState, useEffect } from "react";

function CoordenadaFlecha() {
const [posicion, setPosicion] = useState({ x: 0, y: 0 })

useEffect(() => {
window.addEventListener('mousemove', fijarPosicion)
return () => {
window.removeEventListener('mousemove', fijarPosicion)
console.log('se borro el registro de eventos')
}
}, [])

function fijarPosicion(e) {
setPosicion({ x: e.clientX, y: e.clientY })
}

return (
<div>
<p>{posicion.x} - {posicion.y}</p>
</div>
);
}

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=9&codigo=9&inicio=0 8/11
25/4/23, 09:36 Hook de efecto (función useEffect)

export default CoordenadaFlecha;

A la función 'useEffect' le pasamos como primer parámetro la función flecha que registra la escucha del evento 'mousemove'
y además retorna una función flecha que se ejecutará cuando se borre la componente 'CoordenadaFlecha' desde la función
'App':

useEffect(() => {
window.addEventListener('mousemove', fijarPosicion)
return () => {
window.removeEventListener('mousemove', fijarPosicion)
console.log('se borro el registro de eventos')
}
}, [])

Además le pasamos como segundo parámetro a la función useEffect un vector vacío con el objetivo que se ejecute una
única vez.

El código fuente de la componente 'App':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=9&codigo=9&inicio=0 9/11
25/4/23, 09:36 Hook de efecto (función useEffect)

import { useState } from "react";


import CoordenadaFlecha from './CoordenadaFlecha';

function App() {

const [visible, setVisible] = useState(true)

function ocultar() {
setVisible(false)
}

return (
<div>
{visible ? <CoordenadaFlecha /> : <p>Se oculto la coordenada</p>}
<button onClick={ocultar}>Ocultar</button>
</div>
);
}

export default App

Cuando se presiona el botón ocultar se llama a la función 'ocultar' que cambia la variable de estado visible por el valor falso,
esto hace que la componente CoordenadaFlecha no se renderize y muestre el mensaje 'Se oculto la coordenada':

{visible ? <CoordenadaFlecha /> : <p>Se oculto la coordenada</p>}

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=9&codigo=9&inicio=0 10/11
25/4/23, 09:36 Hook de efecto (función useEffect)

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=9&codigo=9&inicio=0 11/11
25/4/23, 10:00 Peticiones con la API fetch en React

10 - Peticiones con la API fetch en React

Cuando necesitamos hacer peticiones a un servidor web podemos utilizar el API fetch de Javascript. Nos permite obtener
en forma asíncrona recursos de un servidor web.

Problema
Confeccionar una aplicación que recupere una respuesta en JSON de la dirección:

https://scratchya.com.ar/react/datos.php

La estructura del archivo JSON es:

[
{
"codigo": 1,
"descripcion": "papas",
"precio": 12.33
},
{
"codigo": 2,
"descripcion": "manzanas",
"precio": 54
}
]

Luego de recuperar los datos mostrarlos en una tabla HTML

El primer paso será crear el proyecto010 desde la línea de comandos de Node.js mediante la aplicación create-react-app

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=10&codigo=10&inicio=0 1/10
25/4/23, 10:00 Peticiones con la API fetch en React

import { useState, useEffect } from 'react';

function App() {

const [articulos, setArticulos] = useState([])

useEffect(() => {
fetch('https://scratchya.com.ar/react/datos.php')
.then((response) => {
return response.json()
})
.then((articulos) => {
setArticulos(articulos)
})
}, [])

return (
<div>
<table border="1">
<thead>
<tr>
<th>Código</th>
<th>Descripción</th>
<th>Precio</th>
</tr>
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=10&codigo=10&inicio=0 2/10
25/4/23, 10:00 Peticiones con la API fetch en React

</thead>
<tbody>
{articulos.map(art => {
return (
<tr key={art.codigo}>
<td>{art.codigo}</td>
<td>{art.descripcion}</td>
<td>{art.precio}</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}

export default App

Recordemos que uno de los objetivos de los Hook de efectos son las peticiones de datos a un servidor:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=10&codigo=10&inicio=0 3/10
25/4/23, 10:00 Peticiones con la API fetch en React

useEffect(() => {
fetch('https://scratchya.com.ar/react/datos.php')
.then((response) => {
return response.json()
})
.then((articulos) => {
setArticulos(articulos)
})
}, [])

Definimos una variable de estado para almacenar un arreglo con todos los productos recuperados del servidor:

const [articulos, setArticulos] = useState([])

El el bloque JSX se muestra la cabecera de la tabla HTML y mediante el recorrido de la variable de estado se muestran los
artículos recuperados del servidor:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=10&codigo=10&inicio=0 4/10
25/4/23, 10:00 Peticiones con la API fetch en React

return (
<div>
<table border="1">
<thead>
<tr>
<th>Código</th>
<th>Descripción</th>
<th>Precio</th>
</tr>
</thead>
<tbody>
{articulos.map(art => {
return (
<tr key={art.codigo}>
<td>{art.codigo}</td>
<td>{art.descripcion}</td>
<td>{art.precio}</td>
</tr>
);
})}
</tbody>
</table>
</div>
);

Cuando ejecutamos la aplicación tenemos como resultado:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=10&codigo=10&inicio=0 5/10
25/4/23, 10:00 Peticiones con la API fetch en React

Cuando hay peticiones a un servidor puede haber un tiempo de espera hasta que se recuperan los datos. Vamos a modificar
el ejercicio anterior para que se muestre un mensaje hasta que lleguen los datos del servidor:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=10&codigo=10&inicio=0 6/10
25/4/23, 10:00 Peticiones con la API fetch en React

import { useState, useEffect } from 'react';

function App() {

const [articulos, setArticulos] = useState([])


const [recuperado, setRecuperado] = useState(false)

function mostrarTabla() {
return (
<div>
<table border="1">
<thead>
<tr>
<th>Código</th>
<th>Descripción</th>
<th>Precio</th>
</tr>
</thead>
<tbody>
{articulos.map(art => {
return (
<tr key={art.codigo}>
<td>{art.codigo}</td>
<td>{art.descripcion}</td>
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=10&codigo=10&inicio=0 7/10
25/4/23, 10:00 Peticiones con la API fetch en React

<td>{art.precio}</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}

useEffect(() => {
fetch('https://scratchya.com.ar/react/datos.php')
.then((response) => {
return response.json()
})
.then((articulos) => {
setArticulos(articulos)
setRecuperado(true)
})
}, [])

if (recuperado)
return mostrarTabla()
else
return (<div>recuperando datos...</div>)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=10&codigo=10&inicio=0 8/10
25/4/23, 10:00 Peticiones con la API fetch en React

export default App

Hemos guardado dos variables de estado, el vector con los datos a imprimir y una bandera que indica si los datos fueron
recuperados del servidor:

const [articulos, setArticulos] = useState([])


const [recuperado, setRecuperado] = useState(false)

Cuando realmente tenemos todos los datos recuperados procedemos a modificar las dos variables de estado:

useEffect(() => {
fetch('https://scratchya.com.ar/react/datos.php')
.then((response) => {
return response.json()
})
.then((articulos) => {
setArticulos(articulos)
setRecuperado(true)
})
}, [])

Donde generamos el bloque JSX, según la variable de estado 'recuperado' procedemos a mostrar la tabla HTML o un div
con un mensaje de información:

if (recuperado)
return mostrarTabla()
else
return (<div>recuperando datos...</div>)

Posiblemente el tiempo de respuesta en este problema es muy pequeño y no alcancemos a ver el mensaje por pantalla,
podemos modificar temporalmente el programa y hacer que espere 2 segundos antes de recuperar los datos (esto es solo a
modo de prueba y no tiene sentido en este problema esperar):
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=10&codigo=10&inicio=0 9/10
25/4/23, 10:00 Peticiones con la API fetch en React

useEffect(() => {
fetch('https://scratchya.com.ar/react/datos.php')
.then((response) => {
return response.json()
})
.then((articulos) => {
setTimeout(() => {
setArticulos(articulos)
setRecuperado(true)
}, 2000);
})
}, [])

Con esto tenemos la oportunidad de ver el mensaje:

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=10&codigo=10&inicio=0 10/10
25/4/23, 10:53 Propiedad key en listas de datos

11 - Propiedad key en listas de datos

En un concepto anterior vimos como mostrar, modificar y borrar elementos de una vector almacenado en el 'estado' de la
componente. Si volvemos a ejecutar la aplicación y activamos la opción del navegador para ver "Las herramientas para
desarrolladores" podremos comprobar que React nos informa de un "Warning":

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=11&codigo=11&inicio=0 1/6
25/4/23, 10:53 Propiedad key en listas de datos

Este problema se debe a que React nos informa que debemos definir una propiedad en las listas de datos para permitir que
React sea más eficiente en el agregado, modificación y borrado de elementos.

En el atributo key debemos asignar un valor distinto para cada elemento.

Problema
Crear un nuevo proyecto con la herramienta create-react-app llamado proyecto011

Almacenar en una variable de estado de la componente el siguiente vector:

articulos: [{
codigo: 1,
descripcion: 'papas',
precio: 12.52
},{
codigo: 2,
descripcion: 'naranjas',
precio: 21
},{
codigo: 3,
descripcion: 'peras',
precio: 18.20
}]

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=11&codigo=11&inicio=0 2/6
25/4/23, 10:53 Propiedad key en listas de datos

import { useState } from "react";

function App() {

function borrar(cod) {
const temp = articulos.filter((art)=>art.codigo !== cod);
setArticulos(temp)
}

const [articulos, setArticulos] = useState([{


codigo: 1,
descripcion: 'papas',
precio: 12.52
}, {
codigo: 2,
descripcion: 'naranjas',
precio: 21
}, {
codigo: 3,
descripcion: 'peras',
precio: 18.20
}]);

return (
<div>
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=11&codigo=11&inicio=0 3/6
25/4/23, 10:53 Propiedad key en listas de datos

<table border="1">
<thead><tr><th>Código</th><th>Descripción</th><th>Precio</th><th>Borr
<tbody>
{articulos.map(art => {
return (
<tr key={art.codigo}>
<td>
{art.codigo}
</td>
<td>
{art.descripcion}
</td>
<td>
{art.precio}
</td>
<td>
<button onClick={() => borrar(art.codigo)}>Borrar</button>
</td>
</tr>
)
})}
</tbody>
</table>
</div>
);

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=11&codigo=11&inicio=0 4/6
25/4/23, 10:53 Propiedad key en listas de datos

export default App;

Cuando generamos la lista de filas de la tabla añadimos la propiedad 'key' a cada elemento HTML 'tr' (utilizamos el atributo
codigo que es la clave primaria en el vector de artículos):

{articulos.map(art => {
return (
<tr key={art.codigo}>
<td>
{art.codigo}
</td>
<td>
{art.descripcion}
</td>
<td>
{art.precio}
</td>
<td>
<button onClick={() => borrar(art.codigo)}>Borrar</button>
</td>
</tr>
)
})}

Ahora si ejecutamos la aplicación podemos comprobar que no se genera el "Warning".

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=11&codigo=11&inicio=0 5/6
25/4/23, 10:53 Propiedad key en listas de datos

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=11&codigo=11&inicio=0 6/6
25/4/23, 10:59 Formularios: enlace de controles con variables de estados (Hooks de estados)

12 - Formularios: enlace de controles con variables de


estados (Hooks de estados)

Cuando trabajamos con formulario HTML los controles almacenan el valor cargado. Con React es muy común enlazar
cada control de formulario con una o más variables de estado mediante el empleo de Hook.

Este enlace nos facilita implementar validaciones de ingreso de datos inmediatamente después que el operador los carga.

Problema
Confeccionar un formulario HTML que solicite la carga del nombre, edad y si tiene estudios o no una persona. Utilizar
controles:

<input type="text" />


<input type="number" />
<input type="checkbox" />

Almacenar en una variable de estado de la componente cada vez que ocurre un cambio en un control de formulario. Mostrar
en todo momento que datos están almacenado en la variable de estado.

Crear con la aplicación create-react-app el proyecto012

La interfaz visual debe ser:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=12&codigo=12&inicio=0 1/7
25/4/23, 10:59 Formularios: enlace de controles con variables de estados (Hooks de estados)

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=12&codigo=12&inicio=0 2/7
25/4/23, 10:59 Formularios: enlace de controles con variables de estados (Hooks de estados)

import { useState } from 'react';

function App() {

const [datos, setDatos] = useState({


nombre: '',
edad: '',
estudios: false
})

function cambioNombre(e) {
setDatos((valores) => ({
...valores,
nombre: e.target.value,
}))
}

function cambioEdad(e) {
setDatos((valores) => ({
...valores,
edad: e.target.value,
}))
}

function cambioEstudio(e) {
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=12&codigo=12&inicio=0 3/7
25/4/23, 10:59 Formularios: enlace de controles con variables de estados (Hooks de estados)

setDatos((valores) => ({
...valores,
estudios: !datos.estudios,
}))
}

function procesar(e) {
e.preventDefault();
alert('Dato cargado ' + datos.nombre + ' '
+datos.edad + ' '
+datos.estudios);
}

return (
<div>
<form onSubmit={procesar}>
<p>Ingrese nombre:<input type="text" value={datos.nombre} onChange={c
<p>Ingrese edad:<input type="number" value={datos.edad} onChange={cam
<p>Estudios:<input type="checkbox" value={datos.estudios} onChange={c
<p><input type="submit" /></p>
</form>
<hr />
<h3>Datos Ingresados</h3>
<p>Nombre:{datos.nombre}</p>
<p>Edad:{datos.edad}</p>

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=12&codigo=12&inicio=0 4/7
25/4/23, 10:59 Formularios: enlace de controles con variables de estados (Hooks de estados)

<p>Estudios:{datos.estudios ? 'con estudios' : 'sin estudios'}</p>


</div>
);
}

export default App;

Definimos un Hook de estado con un objeto con tres atributos que almacenarán los valores ingresados en el formulario:

const [datos, setDatos] = useState({


nombre: '',
edad: '',
estudios: false
})

En el bloque JSX mostramos los datos actuales de la variable de estado asignando a la propiedad value el valor
almacenado en cada atributo del objeto:

return (
<div>
<form onSubmit={procesar}>
<p>Ingrese nombre:<input type="text" value={datos.nombre} onChange={cambioNombre} /></p>
<p>Ingrese edad:<input type="number" value={datos.edad} onChange={cambioEdad} /></p>
<p>Estudios:<input type="checkbox" value={datos.estudios} onChange={cambioEstudios} /></p>
<p><input type="submit" /></p>
</form>
<hr />

También definimos para cada evento onChange un método que sincronizará el control con el 'estado'.

Mostramos los valores almacenados en todo momento en la variable de estado:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=12&codigo=12&inicio=0 5/7
25/4/23, 10:59 Formularios: enlace de controles con variables de estados (Hooks de estados)

<h3>Datos Ingresados</h3>
<p>Nombre:{datos.nombre}</p>
<p>Edad:{datos.edad}</p>
<p>Estudios:{datos.estudios ? 'con estudios' : 'sin estudios'}</p>
</div>
);

En las funciones cambioNombre, cambioEdad y cambioEstudio actualizamos el estado respectivo llamando a la función
setDatos (recordemos que esto hace que se actualice la página solo en aquellos lugares que lo necesiten):

function cambioNombre(e) {
setDatos((valores) => ({
...valores,
nombre: e.target.value,
}))
}

function cambioEdad(e) {
setDatos((valores) => ({
...valores,
edad: e.target.value,
}))
}

function cambioEstudio(e) {
setDatos((valores) => ({
...valores,
estudios: !datos.estudios,
}))
}

Cuando se presiona el botón submit mediante un alert mostramos los datos cargados en la variable de estado:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=12&codigo=12&inicio=0 6/7
25/4/23, 10:59 Formularios: enlace de controles con variables de estados (Hooks de estados)

function procesar(e) {
e.preventDefault();
alert('Dato cargado ' + datos.nombre + ' '
+datos.edad + ' '
+datos.estudios);
}

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=12&codigo=12&inicio=0 7/7
25/4/23, 11:01 Formularios: validación inmediata

13 - Formularios: validación inmediata

Vimos en el concepto anterior lo usual en React es asociar a cada control de un formulario HTML un 'estado' en la
componente. Esto nos permite inmediatamente se produzca el cambio reaccionar ya sea aceptando o rechazando dicho
dato.

Cada vez que se realiza la carga de datos es un momento muy adecuado para implementar validaciones y no cambiar el
'estado' si los datos son incorrecto.

Problema
Confeccionar una aplicación que permita ingresar en un control 'input' de tipo 'text' solo valores binarios, es decir solo ceros
y unos.

Como primer paso creamos una aplicación con create-react-app proyecto013

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=13&codigo=13&inicio=0 1/4
25/4/23, 11:01 Formularios: validación inmediata

import { useState } from 'react';

function App() {
const [numero, setNumero] = useState('')

function cambioNumero(event) {
const entrada = event.target.value;
let cant = 0;
for (let x = 0; x < entrada.length; x++)
if (entrada[x] === '0' || entrada[x] === '1')
cant++;
if (cant === entrada.length)
setNumero(entrada)
}

return (
<div>
<p>Ingrese un número binario:
<input type="text" value={numero} onChange={cambioNumero} />
</p>
</div>
);
}

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=13&codigo=13&inicio=0 2/4
25/4/23, 11:01 Formularios: validación inmediata

export default App;

Cuando ejecutamos la aplicación solo se permite el ingreso de caracteres '1' y '0':

Definimos el hook donde se almacenará la cadena de unos y ceros:

const [numero, setNumero] = useState('')

En el bloque JSX iniciamos la propiedad value del control 'input' con la variable de estado 'numero' y fijamos la función que
captura cambios en el control:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=13&codigo=13&inicio=0 3/4
25/4/23, 11:01 Formularios: validación inmediata

return (
<div>
<p>Ingrese un número binario:
<input type="text" value={numero} onChange={cambioNumero} />
</p>
</div>
);

Finalmente e la función cambioNumero controlamos que todos los caracteres cargados en el control sean '1' y '0', en caso
afirmativo procedemos a modificar el 'estado' y como sabemos el 'estado' está asociado a la propiedad 'value' del control:

function cambioNumero(event) {
const entrada = event.target.value;
let cant = 0;
for (let x = 0; x < entrada.length; x++)
if (entrada[x] === '0' || entrada[x] === '1')
cant++;
if (cant === entrada.length)
setNumero(entrada)
}

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=13&codigo=13&inicio=0 4/4
25/4/23, 11:02 Formularios: control textarea

14 - Formularios: control textarea

Para enlazar un control HTML de tipo textarea debemos definir la propiedad value en forma similar a los controles input
que hemos visto hasta ahora.

Problema
Mostrar un control de tipo textarea. Cada vez que se ingrese un caracter actualizar la cantidad ingresados dentro del control.

Como primer paso creamos una aplicación con create-react-app proyecto014

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=14&codigo=14&inicio=0 1/4
25/4/23, 11:02 Formularios: control textarea

import { useState } from 'react';

function App() {
const [texto, setTexto] = useState('')

function cambioTexto(e) {
setTexto(e.target.value)
}

return (
<div>
<p><textarea value={texto} onChange={cambioTexto} cols="100" rows="5"><
<p>Cantidad de caracteres ingresados: {texto.length}</p>
</div>
);
}

export default App;

En la variable de 'estado' almacenamos un string inicialmente vacío:

const [texto, setTexto] = useState('')

En bloque JSX disponemos un control de tipo 'textarea' e inicializamos la propiedad 'value' con el 'estado' y escuchamos
eventos de cambio para procesar la entrada de datos y sincronizar el 'estado':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=14&codigo=14&inicio=0 2/4
25/4/23, 11:02 Formularios: control textarea

return (
<div>
<p><textarea value={texto} onChange={cambioTexto} cols="100" rows="5"></textarea></p>
<p>Cantidad de caracteres ingresados: {texto.length}</p>
</div>
);

Cada vez que produce un cambio el operador dentro del 'textarea' se ejecuta la función 'cambiarTexto' donde actualizamos
el 'estado' llamando a la función 'setTexto':

function cambioTexto(e) {
setTexto(e.target.value)
}

En pantalla tenemos como resultado:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=14&codigo=14&inicio=0 3/4
25/4/23, 11:02 Formularios: control textarea

Problema propuesto
Modificar el ejercicio anterior disponiendo dos controles de tipo 'textarea', de tal forma que lo que se cargue en uno se refleje
en forma inmediata en el otro.

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=14&codigo=14&inicio=0 4/4
25/4/23, 11:03 Formularios: control select

15 - Formularios: control select

Otro control que debemos ver como lo trabaja la librería React es el 'select'.

Veamos como procesar un control HTML select de selección única. Debemos definir la propiedad value directamente al
elemento 'select' y asociarlo con el 'estado'.

Problema
Mostrar en un control de tipo 'select' los días de la semana. Cuando el operador lo selecciona mostrar cual se seleccionó en
la página.

Como primer paso creamos una aplicación con create-react-app proyecto015

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=15&codigo=15&inicio=0 1/7
25/4/23, 11:03 Formularios: control select

import {useState} from 'react';

function App() {
const [dia,setDia]=useState('Lunes')

function cambioDia(e) {
setDia(e.target.value)
}

return (
<div>
<p><select value={dia} onChange={cambioDia}>
<option>Lunes</option>
<option>Martes</option>
<option>Miércoles</option>
<option>Jueves</option>
<option>Viernes</option>
<option>Sábado</option>
<option>Domingo</option>
</select></p>
<p>Día seleccionado:{dia}</p>
</div>
);
}

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=15&codigo=15&inicio=0 2/7
25/4/23, 11:03 Formularios: control select

export default App;

Creamos una variable de estado con un string que corresponde al primer elemento del control select:

const [dia,setDia]=useState('Lunes')

En bloque JSX definimos la etiqueta 'select' inicializamos la propiedad value con la variable de estado 'dia':

return (
<div>
<p><select value={dia} onChange={cambioDia}>
<option>Lunes</option>
<option>Martes</option>
<option>Miércoles</option>
<option>Jueves</option>
<option>Viernes</option>
<option>Sábado</option>
<option>Domingo</option>
</select></p>
<p>Día seleccionado:{dia}</p>
</div>
);

Cada vez que el operador selecciona un elemento del control 'select' lo acualizamos al dispararse el evento onChange:

function cambioDia(e) {
setDia(e.target.value)
}

En el navegador tenemos:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=15&codigo=15&inicio=0 3/7
25/4/23, 11:03 Formularios: control select

Problema
Modificar el ejercicio anterior para permitir las selecciones múltiples del control HTML 'select'.

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=15&codigo=15&inicio=0 4/7
25/4/23, 11:03 Formularios: control select

import {useState} from 'react';

function App() {
const [dias,setDias]=useState(['Lunes','Miércoles'])

function cambioDias(e) {
const opciones = e.target.options
const seleccionadas = []
for (let i = 0; i < opciones.length; i++) {
if (opciones[i].selected) {
seleccionadas.push(opciones[i].value)
}
}
setDias(seleccionadas)
}

return (
<div>
<p><select multiple value={dias} onChange={cambioDias}>
<option>Lunes</option>
<option>Martes</option>
<option>Miércoles</option>
<option>Jueves</option>
<option>Viernes</option>
<option>Sábado</option>
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=15&codigo=15&inicio=0 5/7
25/4/23, 11:03 Formularios: control select

<option>Domingo</option>
</select></p>
Días seleccionados:{dias.map((dia)=>{
return (<p>{dia}</p>)
}
)}
</div>
);
}

export default App;

Creamos una variable de estado mediante un Hook que almacene un vector de string:

const [dias,setDias]=useState(['Lunes','Miércoles'])

Cuando se dispara el evento de cambio cuando el operador selecciona una o más opciones procedemos a verificar cuales
son las seleccionadas y generar un nuevo vector que le asignaremos a la variable de estado de la componente llamada dias
y accedida por la función setDias:

function cambioDias(e) {
const opciones = e.target.options
const seleccionadas = []
for (let i = 0; i < opciones.length; i++) {
if (opciones[i].selected) {
seleccionadas.push(opciones[i].value)
}
}
setDias(seleccionadas)
}

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=15&codigo=15&inicio=0 6/7
25/4/23, 11:03 Formularios: control select

En el navegador tenemos:

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=15&codigo=15&inicio=0 7/7
25/4/23, 11:04 Formularios: controles radio

16 - Formularios: controles radio

Otro elemento muy común en un formulario HTML son los controles 'radio'. Veremos como podemos almacenar en el
'estado' cual elemento radio se encuentra seleccionado en todo momento.

Problema
Disponer tres controles de tipo radio que se encuentren asociados que representan si la persona tiene estudios 'primario',
'secundario' o 'universitario'.

Como primer paso creamos una aplicación con create-react-app proyecto016

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=16&codigo=16&inicio=0 1/4
25/4/23, 11:04 Formularios: controles radio

import { useState } from 'react';

function App() {
const [estudios, setEstudios] = useState('primario')

function cambioEstudios(e) {
setEstudios(e.target.value)
}

return (
<div>
<p><input type="radio" value="primario" checked={estudios === 'primario
onChange={cambioEstudios} />Primario</p>
<p><input type="radio" value="secundario" checked={estudios === 'secund
onChange={cambioEstudios} />Secundario</p>
<p><input type="radio" value="universitario" checked={estudios === 'uni
onChange={cambioEstudios} />Universitario</p>
<p>Estudio seleccionado: {estudios}</p>
</div>
);
}

export default App;

Definimos una variable de estado con el tipo de estudios con un valor por defecto:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=16&codigo=16&inicio=0 2/4
25/4/23, 11:04 Formularios: controles radio

const [estudios, setEstudios] = useState('primario')

En el bloque JSX en la propiedad checked debemos almacenar un 'true' si queremos que el control 'radio' aparezca
seleccionado y un false en caso contrario. Disponemos una expresión que retorna true o false:

<p><input type="radio" value="primario" checked={estudios === 'primario'}


onChange={cambioEstudios} />Primario</p>

Cada vez que el operador selecciona un radio se ejecuta la función cambioEstudios donde actualizamos el 'estado' con el
valor del 'radio' seleccionado:

function cambioEstudios(e) {
setEstudios(e.target.value)
}

Al cambiar el 'estado' se vuelve a actualizar la componente y se actualiza el nuevo 'radio' seleccionado.

En el navegador tenemos:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=16&codigo=16&inicio=0 3/4
25/4/23, 11:04 Formularios: controles radio

Si no queremos administrar los controles radio con React deberemos definir la propiedad 'name' almacenando un mismo
valor en todos los radios que estén agrupados:

<p><input type="radio" value="primario" name="estudios" />Primario</p>


<p><input type="radio" value="secundario" name="estudios" />Secundario</p>
<p><input type="radio" value="universitario" name="estudios" />Universitario</p>

Dependiendo de la aplicación que tenemos que desarrollar necesitaremos tener o no un control de los 'radio' mediante el
'estado' de React.

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=16&codigo=16&inicio=0 4/4
25/4/23, 11:16 Subir la aplicación React a nuestro hosting

17 - Subir la aplicación React a nuestro hosting

Cuando tenemos lista la aplicación debemos subir la misma a nuestro hosting, para ello debemos empaquetarla utilizando
la aplicación npm.

Vamos a crear una aplicación y posteriormente ver los pasos para subir la misma al sitio web.

Problema
Crear una aplicación que muestre un tablero de ajedrez y permita mediante drag and drop arrastras piezas.

1. Como primer paso creamos una aplicación con create-react-app:

npx create-react-app proyecto017

2. Creamos dos componentes, una llamada Tablero y otra llamada Casilla. Tenemos luego tres componentes en total:
App, Tablero y Casilla:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=17&codigo=17&inicio=0 1/11
25/4/23, 11:16 Subir la aplicación React a nuestro hosting

Debemos además modificar el archivo App.js donde creamos una componente de tipo Tablero.

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=17&codigo=17&inicio=0 2/11
25/4/23, 11:16 Subir la aplicación React a nuestro hosting

import Tablero from './Tablero';


function App() {

return (<div>
<h1>Tablero de ajedrez con Drag and Drop 😀</h1>
<Tablero/>
</div>);
}

export default App;

Tablero.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=17&codigo=17&inicio=0 3/11
25/4/23, 11:16 Subir la aplicación React a nuestro hosting

import Casilla from './Casilla';


import './Tablero.css';
import { useEffect, useState } from "react";
function Tablero() {
const [tablero, setTablero] = useState(
[
['\u265C', '\u265E', '\u265D','\u265A', '\u265A', '\u265D', '
['\u265F', '\u265F', '\u265F','\u265F', '\u265F', '\u265F', '
['', '', '','', '', '', '', ''],
['', '', '','', '', '', '', ''],
['', '', '','', '', '', '', ''],
['', '', '','', '', '', '', ''],
['\u2659', '\u2659', '\u2659','\u2659', '\u2659', '\u2659', '
['\u2656', '\u2658', '\u2657','\u2655', '\u2654', '\u2657', '
]
)
useEffect(() => {

function drag(ev) {
ev.dataTransfer.setData("fila", ev.target.attributes.fila.val
ev.dataTransfer.setData("columna", ev.target.attributes.colum
ev.dataTransfer.setData("valor", ev.target.attributes.valor.v
}

function permitirDrop(ev) {
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=17&codigo=17&inicio=0 4/11
25/4/23, 11:16 Subir la aplicación React a nuestro hosting

ev.preventDefault();
}

function drop(ev) {

ev.preventDefault();
const fila = parseInt(ev.dataTransfer.getData("fila"))
const columna = parseInt(ev.dataTransfer.getData("columna"))
const valor = ev.dataTransfer.getData("valor")
let nuevo = [...tablero];
for (let f = 0; f < 8; f++) {
for (let c = 0; c < 8; c++) {
if (parseInt(ev.target.attributes.fila.value) === f &
nuevo[f][c] = valor
if (f!==fila || c!==columna)
nuevo[fila][columna] = ''
}
}
}
setTablero(nuevo)
}

const casillas = document.querySelectorAll('.casilla')


for (let casilla of casillas) {
casilla.addEventListener('dragstart', drag)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=17&codigo=17&inicio=0 5/11
25/4/23, 11:16 Subir la aplicación React a nuestro hosting

casilla.addEventListener('dragover', permitirDrop);
casilla.addEventListener('drop', drop);
}
return () => {
const casillas = document.querySelectorAll('.casilla')
for (let casilla of casillas) {
casilla.removeEventListener('dragstart', drag)
casilla.removeEventListener('dragover', permitirDrop);
casilla.removeEventListener('drop', drop);
}
}
}, [tablero])

return (
<div className="tablero">
{tablero.map((fila, indicef) => {
return fila.map((casilla, indicec) => {
return (<Casilla valor={casilla} fila={indicef} colum
})
})}
</div>
);
}

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=17&codigo=17&inicio=0 6/11
25/4/23, 11:16 Subir la aplicación React a nuestro hosting

export default Tablero

Tablero.cs

.tablero {
display: grid;
grid-template-rows: repeat(8, 60px);
grid-template-columns: repeat(8, 60px);
}

Casilla.js

import './Casilla.css'
function Casilla(props) {
return (
<span fila={props.fila} columna={props.columna} draggable="true"
);
}

export default Casilla

Casilla.css

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=17&codigo=17&inicio=0 7/11
25/4/23, 11:16 Subir la aplicación React a nuestro hosting

.casillanegra {
background-color:gray;
width: 60px;
height: 60px;
font-size: 50px;
text-align: center;

.casillablanca {
background-color:yellow;
width: 60px;
height: 60px;
font-size: 50px;
text-align: center;

3. Ya tenemos la aplicación ejecutandose correctamente en forma local en nuestra computadora:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=17&codigo=17&inicio=0 8/11
25/4/23, 11:16 Subir la aplicación React a nuestro hosting

Abrimos el archivo 'package.json' y agregamos la propiedad "homepage":

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=17&codigo=17&inicio=0 9/11
25/4/23, 11:16 Subir la aplicación React a nuestro hosting

Disponemos el nombre de dominio donde se ejecutará la aplicación React por ejemplo:

https://www.scratchya.com.ar

Es muy importante tener en cuenta que si almacenamos la aplicación en una subcarpeta de nuestro hosting debemos
indicar la misma, por ejemplo yo la almacené en:

https://www.scratchya.com.ar/reactya/proyecto017/

4. Creamos la aplicación con npm:

npm run build

Debemos subir a nuestro hosting todo el contenido de la carpeta 'build' que se crea con el comando anterior.
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=17&codigo=17&inicio=0 10/11
25/4/23, 11:16 Subir la aplicación React a nuestro hosting

Podemos probar ahora la aplicación recuperando la misma desde nuestro hosting: Tablero ajedrez
(https://www.scratchya.com.ar/reactya/proyecto017/)

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=17&codigo=17&inicio=0 11/11
27/4/23, 09:34 Mostrar imágenes localizadas en la carpeta public

18 - Mostrar imágenes localizadas en la carpeta public

La primer forma de trabajar con imágenes es React, es localizando los mismos en la carpeta public o una subcarpeta de la
misma.

Si abrimos el archivo index.html que tiene todo proyecto en React podremos ver que el archivo favicon.ico se localiza en la
carpeta public:

<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />

Luego cuando compilamos la aplicación React se remplaza la variable de entorno PUBLIC_URL y queda según el valor
inicializado (si no hacemos nada cuando creamos un proyecto luego tiene un path nulo):

<link rel="icon" href="/favicon.ico" />

Con un problema veremos como trabajar con una serie de imágenes.

Problema
Crear una aplicación que muestre una bandera de un país una a la vez, permitir con dos botones cambiar a la siguiente o
anterior bandera.

1. Como primer paso creamos una aplicación con create-react-app:

npx create-react-app proyecto018

2. Creamos en la carpeta 'public' una subcarpeta llamada 'imagenes' y en la misma almacenamos 8 imágenes de
banderas:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=18&codigo=18&inicio=0 1/6
27/4/23, 09:34 Mostrar imágenes localizadas en la carpeta public

3. Modificamos el archivo App.js:

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=18&codigo=18&inicio=0 2/6
27/4/23, 09:34 Mostrar imágenes localizadas en la carpeta public

import React from 'react'

export default function App() {


const banderasPaises = ['argentina.png', 'chile.png', 'uruguay.png', 'b

const [banderaSeleccionada, setBanderaSeleccionada] = React.useState(0)

function banderaSiguiente() {
if (banderaSeleccionada < banderasPaises.length - 1) {
setBanderaSeleccionada(banderaSeleccionada + 1)
}
}

function banderaPrevia() {
if (banderaSeleccionada > 0) {
setBanderaSeleccionada(banderaSeleccionada - 1)
}
}

return (
<div>
<h1>Banderas de paises Latinoamericanos</h1>
<p><img src={process.env.PUBLIC_URL + "/imagenes/" + banderasPaises
<p>
<input type="button" value="<" onClick={banderaPrevia} />
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=18&codigo=18&inicio=0 3/6
27/4/23, 09:34 Mostrar imágenes localizadas en la carpeta public

<input type="button" value=">" onClick={banderaSiguiente} />


{banderasPaises[banderaSeleccionada]}
</p>
</div>
)
}

Definimos un arreglo con 8 nombres de archivos de las imágenes:

const banderasPaises = ['argentina.png', 'chile.png', 'uruguay.png', 'bolivia.png', 'peru.png', 'venezuela.png', 'brasil.

Definimos un Hook de estado con el número de subíndice del arreglo que indicará la bandera visible actual:

const [banderaSeleccionada, setBanderaSeleccionada] = React.useState(0)

En el bloque JSX procedemos a mostrar la imágen actual mediante la sintaxis:

<p><img src={process.env.PUBLIC_URL + "/imagenes/" + banderasPaises[banderaSeleccionada]} alt="bandera" /></p>

Primero disponemos la variable process.env.PUBLIC_URL, el resto del path es la carpeta 'imagenes' que creamos
nosotros y luego el nombre de la imagen a mostrar la recuperamos del arreglo 'banderasPaises' y utilizamos el valor de
la variable 'banderaSeleccionada' (inicialmente tiene el valor 0)

Para poder cambiar de bandera que se muestra disponemos dos botones:

<input type="button" value="<" onClick={banderaPrevia} />


<input type="button" value=">" onClick={banderaSiguiente} />

Y mediante dos funciones procedemos a incrementar o decrementar la variable 'banderaSeleccionada':

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=18&codigo=18&inicio=0 4/6
27/4/23, 09:34 Mostrar imágenes localizadas en la carpeta public

function banderaSiguiente() {
if (banderaSeleccionada < banderasPaises.length - 1) {
setBanderaSeleccionada(banderaSeleccionada + 1)
}
}

function banderaPrevia() {
if (banderaSeleccionada > 0) {
setBanderaSeleccionada(banderaSeleccionada - 1)
}
}

Podemos probar ahora la aplicación que muestra las imágenes localizadas en la carpeta public/imagenes/: aquí
(https://www.scratchya.com.ar/reactya/proyecto018/)
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=18&codigo=18&inicio=0 5/6
27/4/23, 09:34 Mostrar imágenes localizadas en la carpeta public

Recordar que si subimos nuestra aplicación a una subcarpeta de nuestro servidor debemos modificar el archivo
'package.json', agregando dicho path:

{
"name": "proyecto018",
"homepage": "https://www.scratchya.com.ar/reactya/proyecto018/",
"version": "0.1.0",
"private": true,
....

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=18&codigo=18&inicio=0 6/6
27/4/23, 09:42 Mostrar imágenes localizadas en la carpeta src

19 - Mostrar imágenes localizadas en la carpeta src

Si colocamos las imágenes dentro de la carpeta 'src', React las empaqueta en el proyecto. Esto significa que cuando crea
su aplicación para la producción, las imágenes se agruparán y se minimizarán.

Luego las imágenes se agregan haciendo uso de la palabra clave 'import' o 'require'

import
Problema
Crear una aplicación que muestre una bandera de un país una a la vez, permitir con dos botones cambiar a la siguiente o
anterior bandera. Localizar las imágenes en la carpeta 'src'.

1. Como primer paso creamos una aplicación con create-react-app:

npx create-react-app proyecto019

2. Creamos en la carpeta 'src' una subcarpeta llamada 'imagenes' y en la misma almacenamos 8 imágenes de banderas:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=19&codigo=19&inicio=0 1/9
27/4/23, 09:42 Mostrar imágenes localizadas en la carpeta src

3. Modificamos el archivo App.js:

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=19&codigo=19&inicio=0 2/9
27/4/23, 09:42 Mostrar imágenes localizadas en la carpeta src

import {useState} from 'react'


import argentina from './imagenes/argentina.png';
import bolivia from './imagenes/bolivia.png';
import brasil from './imagenes/brasil.png';
import chile from './imagenes/chile.png';
import colombia from './imagenes/colombia.png';
import peru from './imagenes/peru.png';
import uruguay from './imagenes/uruguay.png';
import venezuela from './imagenes/venezuela.png';

function App() {
const banderas = [argentina, bolivia, brasil, chile, colombia, peru, ur
const [nroBandera, setNroBandera] = useState(0)

function banderaSiguiente() {
if (nroBandera < banderas.length - 1) {
setNroBandera(nroBandera + 1)
}
}

function banderaPrevia() {
if (nroBandera > 0) {
setNroBandera(nroBandera - 1)
}
}
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=19&codigo=19&inicio=0 3/9
27/4/23, 09:42 Mostrar imágenes localizadas en la carpeta src

return (
<div>
<h1>Banderas de paises Latinoamericanos</h1>
<p><img src={banderas[nroBandera]} alt="argentina" /></p>
<p>
<input type="button" value="<" onClick={banderaPrevia} />
<input type="button" value=">" onClick={banderaSiguiente} />
</p>
</div>
);
}

export default App;

Importamos cada imagen con la palabra clave import y hacemos referencia al archivo de la imágen:

import argentina from './imagenes/argentina.png';


import bolivia from './imagenes/bolivia.png';
import brasil from './imagenes/brasil.png';
import chile from './imagenes/chile.png';
import colombia from './imagenes/colombia.png';
import peru from './imagenes/peru.png';
import uruguay from './imagenes/uruguay.png';
import venezuela from './imagenes/venezuela.png';

Creamos un arreglo con la referencia a cada imagen:

const banderas = [argentina, bolivia, brasil, chile, colombia, peru, uruguay, venezuela];

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=19&codigo=19&inicio=0 4/9
27/4/23, 09:42 Mostrar imágenes localizadas en la carpeta src

Definimos un Hook de estado con el número de subíndice del arreglo que indicará la bandera visible actual:

const [nroBandera, setNroBandera] = useState(0)

Mostramos la imagen:

<p><img src={banderas[nroBandera]} alt="argentina" /></p>

Luego según el botón que se presiona llamamos a la función respectiva:

<p>
<input type="button" value="<" onClick={banderaPrevia} />
<input type="button" value=">" onClick={banderaSiguiente} />
</p>

Las dos funciones modifican ea bandera seleccionada:

function banderaSiguiente() {
if (nroBandera < banderas.length - 1) {
setNroBandera(nroBandera + 1)
}
}

function banderaPrevia() {
if (nroBandera > 0) {
setNroBandera(nroBandera - 1)
}
}

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=19&codigo=19&inicio=0 5/9
27/4/23, 09:42 Mostrar imágenes localizadas en la carpeta src

Podemos probar ahora la aplicación que muestra las imágenes localizadas en la carpeta public/imagenes/: aquí
(https://www.scratchya.com.ar/reactya/proyecto019/)

Recordar que si subimos nuestra aplicación a una subcarpeta de nuestro servidor debemos modificar el archivo
'package.json', agregando dicho path:

{
"name": "proyecto019",
"homepage": "https://www.scratchya.com.ar/reactya/proyecto018/",
"version": "0.1.0",
"private": true,
....

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=19&codigo=19&inicio=0 6/9
27/4/23, 09:42 Mostrar imágenes localizadas en la carpeta src

require
Vamos a resolver el mismo problema pero empleando ahora require.

Podemos realizar los cambios en el mismo problema anterior, ya que las imágenes las vamos a recuperar de la misma
carpeta.

Modificamos el archivo App.js:

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=19&codigo=19&inicio=0 7/9
27/4/23, 09:42 Mostrar imágenes localizadas en la carpeta src

import { useState } from 'react'

function App() {
const banderas = ["argentina.png", "bolivia.png", "brasil.png", "chile.png"
const [indice, setIndice] = useState(0)

function banderaSiguiente() {
if (indice < banderas.length - 1) {
setIndice(indice + 1)
}
}

function banderaPrevia() {
if (indice > 0) {
setIndice(indice - 1)
}
}

return (
<div>
<h1>Banderas de paises Latinoamericanos</h1>
<p><img src={require(`./imagenes/${banderas[indice]}`)} alt="bandera" /
<p>
<input type="button" value="<" onClick={banderaPrevia} />
<input type="button" value=">" onClick={banderaSiguiente} />
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=19&codigo=19&inicio=0 8/9
27/4/23, 09:42 Mostrar imágenes localizadas en la carpeta src

</p>
</div>
);
}

export default App;

No disponemos ahora un import por cada imagen, sino mediante la función require indicamos el path y el nombre del archivo
directamente, en nuestro caso lo extraemos del arreglo 'banderas', dependiendo del valor de la variable 'indice':

<p><img src={require(`./imagenes/${banderas[indice]}`)} alt="bandera" /></p>

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=19&codigo=19&inicio=0 9/9
27/4/23, 09:51 Formularios: control select dependiente de otro control select

20 - Formularios: control select dependiente de otro


control select

Una situación común en un formulario web es cuando un control select depende del elemento seleccionado de otro control
select.

Problema
Vamos a crear un control select que muestre distintos rubros (por ejemplo: Microprocesadores, Placas de video, Gabinetes
etc), luego cuando el operador selecciona un rubro, se debe actualizar otro control select que muestra todos los artículos
que pertenecen a dicho rubro, por ejemplo si seleccionar Microprocesadores el segundo select puede mostrar Intel Core I5,
Intel Core I7 etc.

1. Como primer paso creamos una aplicación con create-react-app:

npx create-react-app proyecto020

2. Crearemos en un archivo separado los dos arreglos de objetos donde se almacenan los rubros y los artículos: datos.js
(en la misma carpeta donde se localiza App.js):

datos.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=20&codigo=20&inicio=0 1/9
27/4/23, 09:51 Formularios: control select dependiente de otro control select

const rubros = [{
codigo: 1,
nombre: 'Microprocesadores'
},
{
codigo: 2,
nombre: 'Tarjetas de video'
},
{
codigo: 3,
nombre: 'Gabinetes'
}
]

const articulos = [{
codigo: 1,
codigorubro: 1,
nombre: 'Microprocesador Intel Core i5',
precio: 1000
},
{
codigo: 2,
codigorubro: 1,
nombre: 'Microprocesador Intel Core i7',
precio: 2000
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=20&codigo=20&inicio=0 2/9
27/4/23, 09:51 Formularios: control select dependiente de otro control select

},
{
codigo: 3,
codigorubro: 1,
nombre: 'Microprocesador Intel Core i9',
precio: 3000
},
{
codigo: 4,
codigorubro: 2,
nombre: 'Tarjeta de video MSI GeForce GTX 1080',
precio: 790
},
{
codigo: 5,
codigorubro: 2,
nombre: 'Tarjeta de video MSI GeForce GTX 1060',
precio: 1200
},
{
codigo: 6,
codigorubro: 2,
nombre: 'Tarjeta de video MSI GeForce GTX 1050',
precio: 1800
},

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=20&codigo=20&inicio=0 3/9
27/4/23, 09:51 Formularios: control select dependiente de otro control select

{
codigo: 7,
codigorubro: 3,
nombre: 'Gabinete MSI',
precio: 840
},
{
codigo: 8,
codigorubro: 3,
nombre: 'Gabinete Cooler Master 200 Black',
precio: 1120
}
]

export {articulos}
export {rubros}

rubros es un Array de 3 elementos de tipo objeto donde almacenamos el codigo del rubro y su nombre. articulos es un
segundo Array donde almacenamos objetos con los atributos código, el codigo de rubro, nombre y el precio del
artículo.
3. Veamos el código principal de nuestra aplicación donde se encuentra la funcionalidad del formulario.

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=20&codigo=20&inicio=0 4/9
27/4/23, 09:51 Formularios: control select dependiente de otro control select

import './App.css'
import { useState } from 'react'
import { rubros } from './datos.js'
import { articulos } from './datos.js'

function App() {

const [rubro, setRubro] = useState(rubros[0])


const [articulosRubro, setarticulosRubro] = useState(articulos.filter(a
const [articulo, setArticulo] = useState(articulosRubro[0])

function cambiarRubro(e) {
setRubro(rubros.find(rubro => rubro.codigo === Number.parseInt(e.targ
const articulosrubro = articulos.filter(articulo => articulo.codigoru
setarticulosRubro(articulosrubro)
setArticulo(articulosrubro[0])
}

function cambiarArticulo(e) {
setArticulo(articulosRubro.find(articulo => articulo.codigo === Numbe
}

return (
<div className="formulario">
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=20&codigo=20&inicio=0 5/9
27/4/23, 09:51 Formularios: control select dependiente de otro control select

<div>
<select value={rubro.codigo} onChange={cambiarRubro}>
{rubros.map(rubro => (
<option key={rubro.codigo} value={rubro.codigo}>{rubro.nombre
))}
</select>
</div>
<div>
<select value={articulo.codigo} onChange={cambiarArticulo}>
{articulosRubro.map(articulo => (
<option key={articulo.codigo} value={articulo.codigo}>{articu
))}
</select>
</div>
<div>
<ul>
<li>Rubro:<strong>{rubro.nombre}</strong></li>
<li>Articulo:<strong>{articulo.nombre}</strong></li>
<li>Precio:<strong>{articulo.precio}</strong></li>
</ul>
</div>
</div>
);
}

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=20&codigo=20&inicio=0 6/9
27/4/23, 09:51 Formularios: control select dependiente de otro control select

export default App;

Importamos los arreglos definidos en el archivo 'datos.js':

import { rubros } from './datos.js'


import { articulos } from './datos.js'

El primer control select mediante el método map procedemos a inicializar el atributo value de cada 'option' y muestra
en la etiqueta 'rubro.nombre'. Por otro lado inicializamos la propiedad value de la etiqueta select indicando cual debe
mostrarse seleccionado y el evento 'onChange':

Dbemos inicializar

<select value={rubro.codigo} onChange={cambiarRubro}>


{rubros.map(rubro => (
<option key={rubro.codigo} value={rubro.codigo}>{rubro.nombre}</option>
))}
</select>

Utilizamos un hook de estado para almacenar un objeto que representa el rubro seleccionado:

const [rubro, setRubro] = useState(rubros[0]);

Un segundo hook nos permite almacenar en otro arreglo todos los artículos que pertenecen al rubro seleccionado (por
eso filtramos los artículos que pertenecen al rubro seleccionado):

const [articulosRubro, setarticulosRubro] = useState(articulos.filter(articulo => articulo.codigorubro === rubro.codigo))

Este arreglo almacenado en 'articulosRubro' nos permite actualizar el segundo control select en pantalla:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=20&codigo=20&inicio=0 7/9
27/4/23, 09:51 Formularios: control select dependiente de otro control select

<select value={articulo.codigo} onChange={cambiarArticulo}>


{articulosRubro.map(articulo => (
<option key={articulo.codigo} value={articulo.codigo}>{articulo.nombre}</option>
))}
</select>

Un tercer hook nos permite indicar que artículo debe aparecer seleccionado en el segundo control select:

const [articulo, setArticulo] = useState(articulosRubro[0]);

Cuando el operador cambia el rubro seleccionado en el primer control select, se dispara la función 'cambiarRubro'
donde actualizamos el rubro seleccionado con el código de rubro que recuperamos del parámetro 'e' y actualizamos el
arreglo con los artículos que pertenecen al nuevo rubro. También dejamos seleccionado el primer artículo en el
segundo 'select':

function cambiarRubro(e) {
setRubro(rubros.find(rubro => rubro.codigo === Number.parseInt(e.target.value)))
const articulosrubro = articulos.filter(articulo => articulo.codigorubro === Number.parseInt(e.target.value))
setarticulosRubro(articulosrubro)
setArticulo(articulosrubro[0])
}

Cuando cambiamos de artículo en el segundo select procedemos a actualizar el artículo a mostrar seleccionado:

function cambiarArticulo(e) {
setArticulo(articulosRubro.find(articulo => articulo.codigo === Number.parseInt(e.target.value)))
}

En el archivo de la hoja de estilo.

App.css

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=20&codigo=20&inicio=0 8/9
27/4/23, 09:51 Formularios: control select dependiente de otro control select

select {
padding: 0.5em;
margin: 0.5em;
}

.formulario {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

Podemos probar ahora la aplicación: aquí (https://www.scratchya.com.ar/reactya/proyecto020/)

Retornar (index.php?inicio=0)

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=20&codigo=20&inicio=0 9/9
27/4/23, 09:57 Formularios: control select dependiente de otro control select con peticiones a un servidor

21 - Formularios: control select dependiente de otro


control select con peticiones a un servidor

Vimos en el concepto anterior una situación común de varios controles select que dependen entre si.

Problema
Vamos a crear un control select que muestre distintos rubros (por ejemplo: Microprocesadores, Placas de video, Gabinetes
etc), luego cuando el operador selecciona un rubro, se debe actualizar otro control select que muestra todos los artículos
que pertenecen a dicho rubro, por ejemplo si seleccionar Microprocesadores el segundo select puede mostrar Intel Core I5,
Intel Core I7 etc., pero ahora los datos se encontrarán en un servidor web y haremos peticiones con la función fetch. El
servidor nos responderá con formato JSON.

1. Como primer paso creamos una aplicación con create-react-app:

npx create-react-app proyecto021

2. Veamos el código de nuestra aplicación donde se encuentra la funcionalidad del formulario.

App.js

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=21&codigo=21&inicio=20 1/7
27/4/23, 09:57 Formularios: control select dependiente de otro control select con peticiones a un servidor

import './App.css';
import { useState, useEffect } from 'react';

function App() {

const [rubros, setRubros] = useState([])


const [rubroSeleccionado, setRubroSeleccionado] = useState({})

useEffect(() => {
fetch('https://www.scratchya.com.ar/reactya/proyecto021/recuperarrubr
.then((response) => {
return response.json()
})
.then((rub) => {
setRubros(rub)
setRubroSeleccionado(rub[0])
})
}, [])

const [articulosRubro, setarticulosRubro] = useState([])


const [articuloSeleccionado, setArticuloSeleccionado] = useState([])

useEffect(() => {
if (rubroSeleccionado.codigo)
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=21&codigo=21&inicio=20 2/7
27/4/23, 09:57 Formularios: control select dependiente de otro control select con peticiones a un servidor

fetch('https://www.scratchya.com.ar/reactya/proyecto021/recuperarar
.then((response) => {
return response.json()
})
.then((art) => {
setarticulosRubro(art)
setArticuloSeleccionado(art[0])
})
}, [rubroSeleccionado])

function cambiarRubro(e) {
const rubroSelect = rubros.find(r => Number.parseInt(r.codigo) === Nu
setRubroSeleccionado(rubroSelect)
}

function cambiarArticulo(e) {
setArticuloSeleccionado(articulosRubro.find(articulo => Number.parseI
}

return (
<div className="formulario">
<div>
<select value={rubroSeleccionado.codigo} onChange={cambiarRubro}>

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=21&codigo=21&inicio=20 3/7
27/4/23, 09:57 Formularios: control select dependiente de otro control select con peticiones a un servidor

{rubros.map(rubro => (
<option key={rubro.codigo} value={rubro.codigo}>{rubro.nombre
))}
</select>
</div>
<div>
<select value={articuloSeleccionado.codigo} onChange={cambiarArti
{articulosRubro.map(articulo => (
<option key={articulo.codigo} value={articulo.codigo}>{articu
))}
</select>
</div>
<div>
<ul>
<li>Rubro:<strong>{rubroSeleccionado.nombre}</strong></li>
<li>Articulo:<strong>{articuloSeleccionado.nombre}</strong></li
<li>Precio:<strong>{articuloSeleccionado.precio}</strong></li>
</ul>
</div>
</div>
);
}

export default App;

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=21&codigo=21&inicio=20 4/7
27/4/23, 09:57 Formularios: control select dependiente de otro control select con peticiones a un servidor

Importamos las funciones useState y useEffect:

import { useState, useEffect } from 'react';

Mediante un hook de efecto recuperamos todos los rubres del servidor y procedemos a actualizar la variable rubros:

const [rubros, setRubros] = useState([])


const [rubroSeleccionado, setRubroSeleccionado] = useState({})

useEffect(() => {
fetch('https://www.scratchya.com.ar/reactya/proyecto021/recuperarrubros.php')
.then((response) => {
return response.json()
})
.then((rub) => {
setRubros(rub)
setRubroSeleccionado(rub[0])
})
}, [])

Cuando los datos llegan del servidor procedemos a mostrar todos los rubros y marcar como seleccionado el primero:

<select value={rubroSeleccionado.codigo} onChange={cambiarRubro}>


{rubros.map(rubro => (
<option key={rubro.codigo} value={rubro.codigo}>{rubro.nombre}</option>
))}
</select>

De forma similar recuperamos todos los artículos que coinciden con el rubro seleccionado actual:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=21&codigo=21&inicio=20 5/7
27/4/23, 09:57 Formularios: control select dependiente de otro control select con peticiones a un servidor

const [articulosRubro, setarticulosRubro] = useState([])


const [articuloSeleccionado, setArticuloSeleccionado] = useState([])

useEffect(() => {
if (rubroSeleccionado.codigo)
fetch('https://www.scratchya.com.ar/reactya/proyecto021/recuperararticulos.php?rubro=' + rubroSeleccionado.codigo)
.then((response) => {
return response.json()
})
.then((art) => {
setarticulosRubro(art)
setArticuloSeleccionado(art[0])
})
}, [rubroSeleccionado])

Como vemos el servidor nos retorna solo los artículos del rubro seleccionado actualmente. Luego al modificar la
variable 'articulosRubro' se actualiza el control select en forma automática:

<select value={articuloSeleccionado.codigo} onChange={cambiarArticulo}>


{articulosRubro.map(articulo => (
<option key={articulo.codigo} value={articulo.codigo}>{articulo.nombre}</option>
))}
</select>

el evento de cambio de rubro dispara la función 'cambiarRubro' donde recuperamos el nuevo rubro seleccionado y
actualizamos la variable 'rubroSeleccionado', el cual dispara nuevamente el hook de efecto que recupera los artículos
del nuevo rubro seleccionado:

https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=21&codigo=21&inicio=20 6/7
27/4/23, 09:57 Formularios: control select dependiente de otro control select con peticiones a un servidor

function cambiarRubro(e) {
const rubroSelect = rubros.find(r => Number.parseInt(r.codigo) === Number.parseInt(e.target.value))
setRubroSeleccionado(rubroSelect)
}

function cambiarArticulo(e) {
setArticuloSeleccionado(articulosRubro.find(articulo => Number.parseInt(articulo.codigo) === Number.parseInt(e.target.v
}

En el archivo de la hoja de estilo.


App.css

select {
padding: 0.5em;
margin: 0.5em;
}

.formulario {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}

Podemos probar ahora la aplicación: aquí (https://www.scratchya.com.ar/reactya/proyecto021/)

Retornar (index.php?inicio=20)
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=21&codigo=21&inicio=20 7/7

También podría gustarte