React Completo
React Completo
1 - ¿Qué es React?
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.
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
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.
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
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
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
function App() {
return (
<h1>Hola mundo</h1>
);
}
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
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:
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
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>
);
}
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>
);
}
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:
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.
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
);
}
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:
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:
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:
{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}
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>
);
}
No deben ir las comillas en la asignación de la propiedad href si el valor se extrae de una expresión:
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=3&codigo=3&inicio=0 7/10
24/4/23, 15:18 Formato JSX
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>
);
}
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>
);
}
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):
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:
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.
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=4&codigo=4&inicio=0 1/4
24/4/23, 15:28 Captura de eventos
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);
}
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.
<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)
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.
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)
function App() {
function generarAleatorio() {
const v = Math.trunc(Math.random() * 10);
setNumero(v)
}
return (
<div>
<p>Número aleatorio: {numero}</p>
<button onClick={generarAleatorio}>Generar número aleatorio</button>
</div>
);
}
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):
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'.
function generarAleatorio() {
const v = Math.trunc(Math.random() * 10);
setNumero(v)
}
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)
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)
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)
}
return (
<div>
<p>Números aleatorios:</p>
{numeros.map(num => (<p>{num}</p>))}
<button onClick={generarAleatorios}>Generar números aleatorios</button>
</div>
);
}
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)
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':
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)
function App() {
function eliminarUltimaFila() {
if (articulos.length > 0) {
const temp=Array.from(articulos)
temp.pop()
setArticulos(temp)
}
}
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)
);
}
Llamamos a la función useState para crear la variable de estado y le pasamos el arreglo de objetos
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)
function App() {
function borrar(cod) {
const temp = articulos.filter((art)=>art.codigo !== cod);
setArticulos(temp)
}
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)
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:
Cuando llamamos a una función debemos plantear una función anónima que se le asigna al evento 'onClick'.
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.
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
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:
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 2/11
25/4/23, 08:54 Componentes
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>
);
}
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'
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;
}
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 5/11
25/4/23, 08:54 Componentes
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>
);
}
Lo primero que debemos hacer para poder utilizar la componente Dado es importarla:
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
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
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=6&codigo=6&inicio=0 8/11
25/4/23, 08:54 Componentes
function App() {
function generarValor() {
return Math.trunc(Math.random() * 6) + 1
}
function tirar() {
setNumero1(generarValor())
setNumero2(generarValor())
setNumero3(generarValor())
}
);
}
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:
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())
}
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):
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.
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>
);
}
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.
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
}
]
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=7&codigo=7&inicio=0 3/7
25/4/23, 09:03 Componentes: propiedades
function App() {
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
En la función App definimos la variable de estado donde almacenaremos un arreglo con las distintas operaciones
efectuadas:
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
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:
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>
);
}
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:
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
function App() {
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
Debemos importar primero los dos archivos que contienen las componentes:
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>
);
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>
);
}
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)
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:
function App() {
return (
<div>
Hola Mundo
</div>
);
}
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.
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)
function App() {
function cambiar(e) {
setTexto(e.target.value)
}
return (
<div>
<p><input type="text" onChange={cambiar} /></p>
<p>{texto}</p>
</div>
);
}
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:
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):
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):
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)
Cada vez que se carga o borra un caracter (es decir hay un cambio) se dispara la función 'cambiar':
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)
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)
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)
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)
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.
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)
function App() {
function ocultar() {
setVisible(false)
}
return (
<div>
{visible ? <CoordenadaFlecha /> : <p>Se oculto la coordenada</p>}
<button onClick={ocultar}>Ocultar</button>
</div>
);
}
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':
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
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
[
{
"codigo": 1,
"descripcion": "papas",
"precio": 12.33
},
{
"codigo": 2,
"descripcion": "manzanas",
"precio": 54
}
]
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
function App() {
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>
);
}
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:
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>
);
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
function App() {
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
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:
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);
})
}, [])
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
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.
Problema
Crear un nuevo proyecto con la herramienta create-react-app llamado proyecto011
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
function App() {
function borrar(cod) {
const temp = articulos.filter((art)=>art.codigo !== cod);
setArticulos(temp)
}
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
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>
)
})}
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)
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:
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.
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)
function App() {
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)
Definimos un Hook de estado con un objeto con tres atributos que almacenarán los valores ingresados en el formulario:
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'.
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
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.
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
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
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
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.
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
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>
);
}
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)
}
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
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.
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=15&codigo=15&inicio=0 1/7
25/4/23, 11:03 Formularios: control select
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
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
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>
);
}
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
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'.
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
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>
);
}
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
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:
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)
}
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:
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
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.
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
return (<div>
<h1>Tablero de ajedrez con Drag and Drop 😀</h1>
<Tablero/>
</div>);
}
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
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)
}
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
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"
);
}
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;
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
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
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/
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
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:
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):
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.
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
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
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
Definimos un Hook de estado con el número de subíndice del arreglo que indicará la bandera visible actual:
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)
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
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'.
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
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
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>
);
}
Importamos cada imagen con la palabra clave import y hacemos referencia al archivo de la imágen:
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:
Mostramos la imagen:
<p>
<input type="button" value="<" onClick={banderaPrevia} />
<input type="button" value=">" onClick={banderaSiguiente} />
</p>
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.
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
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>
);
}
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':
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
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.
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() {
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
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
Utilizamos un hook de estado para almacenar un objeto que representa el rubro seleccionado:
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):
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
Un tercer hook nos permite indicar que artículo debe aparecer seleccionado en el segundo control select:
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)))
}
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;
}
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
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.
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() {
useEffect(() => {
fetch('https://www.scratchya.com.ar/reactya/proyecto021/recuperarrubr
.then((response) => {
return response.json()
})
.then((rub) => {
setRubros(rub)
setRubroSeleccionado(rub[0])
})
}, [])
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>
);
}
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
Mediante un hook de efecto recuperamos todos los rubres del servidor y procedemos a actualizar la variable rubros:
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:
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
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:
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
}
select {
padding: 0.5em;
margin: 0.5em;
}
.formulario {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
Retornar (index.php?inicio=20)
https://www.tutorialesprogramacionya.com/reactya/detalleconcepto.php?punto=21&codigo=21&inicio=20 7/7