Contenido
Cuando comienzas con React es común tener dudas si el código que escribes es React o es JavaScript, es una duda muy común ya que si bien es recomendado tener bases fuertes de ES6+ también React es una librería fácil de aprender y con bastante demanda que hace que algunos desarrolladores comiencen con ella aún sin tener una idea clara de ES6.
A lo largo de esta entrada estaremos viendo ejemplos de código de aplicaciones React e iremos paso a paso viendo si el código pertenece a React o es JavaScript. Al momento de esta entrada los Hooks ya son soportados en React, pero esta entrada contará con ejemplos de Class Components y React Hooks.
Import
Empezaremos desde el inicio de una App en React, en la parte superior siempre importas un paquete u otros archivos JavaScript.
import React, { useState, useEffect } from 'react';
Si bien lo que importamos es de React, el import es algo existente en JavaScript, la única diferencia es que en JavaScript colocas el nombre y la extensión pero en React no es necesario.
useState
useState es parte de React Hooks, sin duda es el Hook más utilizado y es un reemplazo a this.SetState(); en useState se aplica una técnica conocida como Array Destructuring, que nos permite sacar 2 valores de un array veamos un ejemplo de useState:
const [ moneda, guardarMoneda] = useState('');
Si bien useState es parte de React, la técnica anteriormente mencionada es lo que se conoce como Array Destructuring, que funciona de la siguiente forma:
const [javascript, react] = ["JavaScript", "React"]; // arreglo 2 elementos
console.log(javascript); // "javascript";
console.log(react); // "react"
Destructuring nos permite extraer un valor pero también generar una variable en una misma linea y es lo que utiliza useState(), el orden es importante ya que si bien nuestras variables react y javascript retornan el valor indicado, si las utilizas en diferente orden el resultado no es el esperado ( y lo mismo pasaria con useState() ).
const [javascript, react] = ["JavaScript", "React"]; // arreglo 2 elementos
console.log(react); // "javascript";
console.log(javascript); // "react"
State
Sin duda es la parte más utilizada e importante en React, es lo que hace que todas nuestras aplicaciones sean rápidas y respondan a las interacciones que hacemos, en un Class Component el State siempre es un objeto de JavaScript, en Hooks ya puede ser cualquier tipo de dato de JavaScript, pero toda la funcionalidad del State ( y la función this.setState() ) son de React.
useEffect
useEffect es un reemplazo a los métodos del ciclo de vida en React Hooks y pertenece únicamente en React ya que no hay un equivalente en JavaScript.
useEffect(() => {
// prevenir ejecución
if(ciudad === '') return;
const consultarAPI = async () => {
const appId = '';
// URL a consultar
const url = `https://api.openweathermap.org/data/2.5/weather?q=${ciudad},${pais}&appid=${appId}`;
// consultar la URL
const respuesta = await fetch(url);
const resultado = await respuesta.json();
// almacenar en el state
guardarResultado(resultado);
}
consultarAPI();
}, [ ciudad, pais ]);
Si bien useEffect pertenece a React, puedes ver que el código dentro de un useEffect es JavaScript: un function expression llamado consultarAPI, fetch API para obtener los resultados de una API, async / await, así que mientras el nombre de useEffect es algo existente en React, el código que utilizamos en él es JavaScript.
Componentes
En React se pueden crear componentes de diferentes formas, veamos una de ellas:
import React from 'react';
const Criptomoneda = () => {
return (
// Lo que se mostrará en pantalla
);
}
export default Criptomoneda;
Si bien la creación de componentes y su re-utilización es una de las características de React, un componente es solo una función – en este caso se le conoce como function expression con un arrow function – también notarás que tenemos un export default, que es un export de JavaScript.
Sin embargo la parte de mostrar un componente en pantalla:
<Criptomonedas />
Si pertenece a React y es una de sus principales características, también lo es pasarle propiedades un componente:
<Criptomonedas
orden="ASC"
/>
Carga Condicional de Componentes
Algunas ocasiones deseas mostrar un componente u otro en base a si algún evento ha pasado en tus aplicaciones, tal vez deseas mostrar un componente con un mensaje dando instrucciones sobre como llenar el formulario y una vez que el usuario llene el formulario y tengamos el resultado de una API, mostrar el componente con el resultado, se le conoce como Carga Condicional de Componentes y el código es de esta forma:
// Mostrar Spinner o resultado
const componente = (cargando) ? <Spinner /> : <Cotizacion resultado={resultado} />
Si bien tanto el componente Spinner como Cotizacion pertenecen a React y se muestran al estilo de React, esta técnica es de programación en general, se le conoce como Operador Ternario y es similar a un IF en una sola línea.
Trabajando con Formularios
Veamos de aquí en adelante una serie de ejemplos en Formularios en React y si el código es JavaScript o React.
Evento onSubmit
React tiene una forma muy particular de leer los datos de un formulario o de un campo en el formulario, lo hace mediante eventos, veamos onSubmit
<form
onSubmit={cotizarMoneda}
>
onSubmit es utilizado para ejecutar una función una vez que el formulario es enviado.
En JavaScript el selector sería el siguiente:
const formulario = document.querySelector('form');
formulario.addEventListener('submit', () => {
// resto del código
});
Evento onChange
onChange es más utilizado cuando el usuario escribe en un campo del formulario, o selecciona una opción de un select o de un radio:
<select
onChange={ e => guardarCriptoCotizar(e.target.value) }
>
Si bien cuando un usuario escribe utilizamos ‘input’, en un select también se puede utilizar ‘click’ o ‘change’, por lo tanto el equivalente sería el código siguiente:
const opciones = document.querySelector('select');
opciones.addEventListener('change', () => {
// resto del código
});
De la misma forma React maneja otros eventos, con el prefijo on como pueden ser onClick y onChange.
Ademas de un addEventListener ‘change’ otras opciones son ‘click’ o ‘input’ pero hay muchas otras opciones, así como muchos otros eventos en React que inician con on: onClick, onKeyPress, onBlur, onFocus, onDoubleClick y muchos más.
Iterando con .map
En React es muy común que cuando tenemos un array y queremos mostrarlo en pantalla se utiliza .map, .map es una función de JavaScript (se les conoce como array methods) y es muy similar a un for loop o un .forEach, la diferencia con .forEach es que crea un nuevo arreglo a diferencia de .forEach que solo sirve para acceder a cada elemento del array.
{ criptomonedas.map(criptomoneda => (
<Criptomoneda
key={criptomoneda.CoinInfo.Id}
criptomoneda={criptomoneda}
/>
))}
El código anterior itera un array de criptomonedas y manda llamar múltiples veces el mismo componente pero en cada iteración le pasa diferente información via props.
Algo importante es que el .map cuando es utilizado en React requiere un key= este key es exclusivo de React y es lo que ayuda a que React sea tan rápido.
Props
Los props es algo bastante común en React, es la forma en que pasas información del componente padre hacia el hijo ( y puede contener cualquier tipo de dato en React incluido funciones ).
// Código en el componente padre
{ criptomonedas.map(criptomoneda => (
<Criptomoneda
key={criptomoneda.CoinInfo.Id}
criptomoneda={criptomoneda}
/>
))};
// Código en el componente hijo.
import React from 'react';
const Criptomoneda = ({criptomoneda}) => {
const { FullName, Name} = criptomoneda.CoinInfo;
return (
<option value={Name}>{FullName}</option>
);
}
export default Criptomoneda;
En el código anterior cuando mandamos llamar el componente <Criptomoneda /> le pasamos un valor (prop) llamado criptomoneda y le pasamos un objeto de información llamado criptomoneda (que se encuentra entre las llaves {}.
En el componente hijo nota como en el parentesis del arrow function pasamos el siguiente valor {criptomoneda} ese código también lo encontrarás como (props), pero en este caso aplicamos destructuring para leer el prop en especifico y evitar utilizar props.
Prop es algo exclusivo de React, pero aplicar destructuring de esta forma es JavaScript (Object destructuring).
Class Components
En React también puedes generar componentes con Classes:
import React, { Component } from 'react';
class App extends Component {
render() {
return(
// resto del código
)
}
}
export default App;
Todo este código es exclusivo de JavaScript, es la forma tradicional de crear una clase en JavaScript, si bien algunas partes son de React, como la función return() es así como se crean classes en React, nota como heredamos de la clase Component de React y gracias a ello podemos utilizar todos los métodos de React en nuestros Componentes.
State en Class Components
El state en un class Component y en un Componente creado con Hooks es un poco diferente, en Class Components siempre es un objeto:
state = {
citas: []
}
Si bien es un objeto, el state es exclusivo de React, y debe crearse siempre como objeto y utilizando la palabra en minusculas de esta forma (cuando es un Class Component).
Reescribir el State en un Class Component
Cuando trabajas con JavaScript y deseas asignar un nuevo valor a una variable puedes hacerlo de esta forma:
let tecnologia = 'JavaScript';
tecnologia = 'JavaScript ES6';
Sin embargo en React si deseas modificar el state no dene hacerse por una asignación de este tipo, es buena práctica no “mutar” o cambiar el state directamente con una asignación de este tipo. Por lo tanto se utiliza la función this.setState();
crearNuevaCita = datos => {
// copiar el state actual
const citas = [...this.state.citas, datos];
// agregar el nuevo state
this.setState({
citas
})
}
El código anterior se puede dividir en 2 partes, el primero que toma una copia del state actual:
const citas = [...this.state.citas, datos];
El código anterior es JavaScript y es lo que se conoce como spread operator y nos permite (entre otras cosas) añadir datos a un arreglo nuevo – siempre crea una copia nueva del arreglo – lo cual es importante ya que no debemos mutar el state directamente, veamos unos ejemplos de spread operator:
const arreglo1 = [1,2,3];
const arreglo2 = [...arreglo1, 4, 5, 6];
console.log(arreglo2);
// resultado: (6) [1, 2, 3, 4, 5, 6]
// utilizando spread al final del array
const arreglo3 = [ 4, 5, 6, ...arreglo1];
console.log(arreglo3);
// resultado: (6) [4, 5, 6, 1, 2, 3]
A diferencia de .push() el spread operator no va a modificar el arreglo principal (arreglo1) por lo tanto es una buena forma de agregar nuevo contenido al array sin modificar el state original.
Y el segundo que reescribe un state:
// agregar el nuevo state
this.setState({
citas
})
Si bien es una función ( o método ) .setState() pertenece a React y sirve para modificar el state original de una forma segura.
Ciclo de Vida de los Componentes
El ciclo de vida de los componentes son funciones que se ejecutan automáticamente cuando ciertos eventos ocurren en React:
// Cuando la aplicación carga
componentDidMount() {
const citasLS = localStorage.getItem('citas');
if(citasLS) {
this.setState({
citas : JSON.parse(citasLS)
})
}
}
// cuando eliminamos o agregamos una nueva cita
componentDidUpdate() {
localStorage.setItem('citas', JSON.stringify(this.state.citas));
}
Estos 2 métodos ( y otros ) son exclusivos de React, no existen en aplicaciones JavaScript (salvo que tú los crees) y deben llamarse de esta forma para que puedan funcionar. Algunos de ellos serán declarados obsoletos en próximas versiones de React en favor de los React Hooks.