Introducci贸n

React es una biblioteca JavaScript altamente eficiente y declarativa que se utiliza para crear interfaces de usuario interactivas.

Fue creado por el ingeniero de Facebook Jordan Walke y se lanz贸 en mayo de 2013.

En los 煤ltimos a帽os, ha superado a sus rivales y ha establecido firmemente su dominio.

React te insita a crear c贸digo declarativo (indicas el qu茅, no el c贸mo) y orientado a componentes.

Un componente es un pieza de c贸digo que puede representar una parte de la interfaz de usuario o una funcionalidad en particular que se puede encapsular y reutilizar en diferentes partes de un desarrollo o incluso en diferentes aplicaciones.

Cada componente reaccionar谩 a cambios internos (en su estado) o externos (nuevas propiedades recibidas) y se volvera a redibujar (renderizado) en la interfaz. Para ello React utiliza su Virtual DOM que es una copia del DOM original del navegador para s贸lo hacer los cambios necesarios en los nodos que hayan reaccionado y evitar redibujar todo el 谩rbol del DOM.

Para poder interactuar con la interfaz React tiene eventos sint茅ticos que son una abstracci贸n de los eventos nativos de los navegadores, para mejorar la compatibilidad y evitar el uso de librer铆as para crossbrowsing (bye bye jQuery 馃き).

驴Por qu茅 usarlo?

Ventajas:

  • Alto rendimiento: React es conocido por su alta eficiencia y flexibilidad. Se puede integrar f谩cilmente con diferentes tecnolog铆as. Se puede usar tanto para el lado del cliente como para el lado del servidor.
  • Recursos abundantes : como Facebook la mantiene, existe una gran cantidad de documentaci贸n y recursos disponibles en la web que hace que la curva de aprendizaje sea muy fluida.
  • Compatibilidad con versiones anteriores : la transici贸n o migraci贸n de versiones anteriores a nuevas es bastante f谩cil y retrocompatible.
  • Estructura de componentes f谩cil de mantener: la arquitectura basada en componentes de React ayuda a aumentar la reutilizaci贸n del c贸digo y facilita bastante el mantenimiento de proyectos a gran escala.
  • Fuerte Comunidad: React tiene m谩s de 1300 colaboradores en GitHub.
  • Documentaci贸n Multi idioma: Actualmente React tiene su documentaci贸n en diferentes idiomas entre ellos el espa帽ol.
  • Flujo de datos unidireccional: el enlace de datos unidireccional y hacia abajo (de componentes padres a hijos), ayuda a garantizar que los cambios realizados en la estructura del componente hijo no afecten la estructura del componente padre.

Desventajas:

  • Complejo: muchos desarrolladores pueden encontrar en un inicio demasiado compleja la curva de aprendizaje de React en comparaci贸n con otros frameworks como el caso de Vue. Dicha complejidad puede ser innecesaria para proyectos a peque帽a escala.
  • JSX: el uso de JSX agrega otra capa de complejidad. JSX es un preprocesador que agrega extensi贸n de sintaxis XML a JavaScript. Aunque JSX ayuda a codificar el c贸digo React de una manera m谩s segura y r谩pida, puede ser dif铆cil de comprender para los nuevos desarrolladores.
  • Necesidad de un ecosistema de muchas herramientas: React requiere una amplia gama de herramientas para funcionar correctamente y ser compatible con otras tecnolog铆as.
  • Problemas de SEO: se sabe que las SPAs (Single Page Applications) creadas con React se enfrentan a problemas de indexaci贸n por parte de los rastreadores y bots de motores de b煤squeda.

驴Qui茅n lo usa?

Grandes empresas como Netflix, Yahoo, Airbnb, Instagram, Facebook, WhatsApp, PayPal, Microsoft, la BBC, Aerom茅xico, etc. Incluso grandes sitios de informaci贸n y noticias que antes usaban WordPress se est谩n migrando a sitios hechos con JAM stack y React como librer铆a principal, tal es el caso de Smashing Magazine.

Estad铆sticas que respaldan su uso:

Entorno y Herramientas de Desarrollo.

React es una librer铆a y no t茅cnicamente un framework. Por lo que s贸lo maneja la capa de Vista, tomando como referencia el modelo MVC (Modelo Vista Controlador) para el desarrollo de aplicaciones web. Sin embargo cuenta con una amplia gama de herramientas, librer铆as y frameworks para complementar su entorno de desarrollo, por ejemplo:

  • Node.js y NPM: Para ejecutar el entorno de desarrollo e instalar dependencias.
  • Yarn: Un gestor de paquetes JavaScript.
  • Webpack: Es un empaquetador de archivos para aplicaciones JavaScript.
  • React Router: Librer铆a para manejar rutas declarativas.
  • Redux: Es una librer铆a para gestionar el estado de las aplicaciones JavaScript.
  • Flux: Es la arquitectura de aplicaciones que Facebook usa para crear aplicaciones web del lado del cliente.
  • Create React App: Un conjunto de configuraciones preestablecidadas para comenzar a trabajar con React ejecutando un s贸lo comando.
  • Gatsby: Es un framework basado en React para desarrollar r谩pidamente sitios y aplicaciones web, usando diferentes fuentes de datos como CMS, Markdowns, APIs, etc.
  • Next.js: Es un framework basado en React para desarrollar sitios est谩ticos y aplicaciones del lado del servidor (SSR - Server Side Rendering).
  • GraphQL: Es un lenguaje de consulta de datos para APIs.
  • React Bootstrap: Es la versi贸n del popular framework frontend Bootstrap pero creado con componentes hechos en React.
  • Material UI: Es un framework frontend inspirado en Material Design creado con componentes hechos en React.
  • React Native: Es un framework basado en React para la creaci贸n de aplicaciones m贸viles y nativas.
  • React Dev Tools Chrome: Es una extensi贸n para Chrome que agrega de herramientas de depuraci贸n para React.
  • React Dev Tools Firefox: Es una extensi贸n para Firefox que agrega de herramientas de depuraci贸n para React.
  • Simple React Snippets for VSCode: Es una extensi贸n para Visual Studio Code que nos permite usar atajos para agilizar la escritura de c贸digo React.

馃敿 Regresar


Create React App

Aunque existen varias formas de empezar con React, una manera sencilla y eficiente es con create-react-app, una aplicaci贸n de consola que nos va a permitir crear aplicaciones React con cero configuraci贸n, lo que nos permitir谩 centrarnos en los m谩s importante: Programar en React.

Para crear una aplicaci贸n utilizamos el comando npx create-react-app seguido del nombre que le quieras dar a tu aplicaci贸n. Por ejemplo:

npx create-react-app my-app

Cuando ejecutas ese comando create-react-app va a crear una carpeta llama my-app con una serie de archivos y subcarpetas para que puedas empezar a trabajar en tu proyecto.

Ingresa a la carpeta my-app y ejecuta el proyecto con los siguientes comandos:

cd my-app
npm start

El 煤ltimo comando ejecuta el servidor de desarrollo y abre un navegador con una pantalla de bienvenida.

隆Felicidades!, has creado tu primera aplicaci贸n con React.

驴Qu茅 incluye create-react-app?

Un proyecto creado con create-react-app, adem谩s de React, incluye librer铆as como:

  • Webpack: que se encarga de procesar y empaquetar nuestro c贸digo JavaScript (con sus dependencias), archivos CSS y otros archivos est谩ticos como im谩genes, vectores, fuentes, etc.
  • Babel: que nos permite usar nuevas caracter铆sticas de ECMAScript.
  • PostCSS que es una librer铆a para el procesamiento de CSS.
  • Jest que es una librer铆a para testing.
  • etc.

Uno podr铆a configurar un proyecto de React manualmente e incluir cada una de estas librer铆as, pero es bastante engorroso, create-react-app nos hace la vida m谩s f谩cil.

Estructura de carpeta

create-react-app crea la siguiente estructura de archivos y carpetas:

my-app/
  README.md
  node_modules/
  package.json
  public/
    index.html
    favicon.ico
  src/
    App.css
    App.js
    App.test.js
    index.css
    index.js
    logo.svg

Los dos archivos m谩s importantes son:

  • public/index.html - la plantilla HTML de la aplicaci贸n.
  • src/index.js - el punto de entrada JavaScript de la aplicaci贸n.

Puedes eliminar o renombrar otros archivos seg煤n tus necesidades.

Dentro de src se incluyen todos los archivos JavaScript y CSS de tu aplicaci贸n.

Tambi茅n es recomendable incluir otros archivos est谩ticos como im谩genes y fuentes en esta carpeta. Puedes crear subcarpetas para organizar mejor los archivos.

En public van todos los archivos est谩ticos que necesites incluir en la plantilla public/index.html.

Puedes crear otras carpetas adem谩s de src y public. Estas carpetas no van a ser inclu铆das en el paquete de distribuci贸n.

Scripts

En la carpeta del proyecto puedes ejecutar los siguientes comandos:

  • npm start - inicia el servidor de desarrollo y abre un navegador con la aplicaci贸n.
  • npm test - ejecuta las pruebas.
  • npm run build - empaqueta la aplicaci贸n para producci贸n en la carpeta build.
  • npm run eject - permite cambiar manualmente las librer铆as y configuraci贸n que utiliza create-react-app por defecto. Ten cuidado con este comando, una vez que se expulsa la configuraci贸n inicial no hay vuelta atr谩s.

Hot reloading

Una de las funcionalidades m谩s importantes de los proyectos creados con create-react-app es la capacidad de hacer cambios en vivo sin necesidad de reiniciar el servidor. Si haces un cambio en alg煤n archivo en src o public el navegador se refresca autom谩ticamente.

馃敿 Regresar


JSX

Es una extensi贸n de la sintaxis de JavaScript que produce elementos de React.

Se puede usar:

  • Dentro de estructuras de control como if y for.
  • Asignarlo a variables.
  • Aceptarlo como argumento o retorno en funciones.
  • Expresiones JavaScript.

Veamos un ejemplo tomado del c贸digo que genera create-react-app:

<div className="App">
  <header className="App-header">
    <img src="{logo}" className="App-logo" alt="logo" />
    <h1 className="App-title">Welcome to React</h1>
  </header>
  <p className="App-intro">
    To get started, edit <code>src/App.js</code> and save to reload.
  </p>
</div>

JSX es similar a HTML pero con algunas diferencias importantes:

Algunas reglas importantes:

  • Toda etiqueta debe cerrarse por ejemplo <br> debera cerrarse a <br />.
  • Los componentes deben devolver un s贸lo elemento padre.
  • Algunos atributos HTML cambian como:
    • class por className.
    • for por htmlFor.
  • Los atributos de un elemento JSX pueden aceptar valores de tipo String entrecomillados o expresiones JavaScript entre llaves, por ejemplo:
    • <img alt="Avatar" src={user.avatarURL} />

JSX se transforma en JavaScript

Por debajo JSX se transforma en c贸digo JavaScript. Por ejemplo, el siguiente c贸digo JSX.

<div class="active">Hola Mundo</div>

se transforma en el siguiente c贸digo JavaScript:

React.createElement("div", { className: "active" }, "Hola mundo");

Puedes utilizar el REPL de Babel para ver en qu茅 se convierte el c贸digo JSX que escribes.

La ventaja de JSX es que, como es JavaScript, podemos:

  1. Ver algunos errores en tiempo de compilaci贸n.

  2. Asignar JSX a variables. Por ejemplo:

    const el = <p>Hola</p>;
  3. Retornar JSX desde m茅todos. Por ejemplo:

     renderText() {
       if (someCondition) {
         return <p>Hola</p>;
       } else {
         return <p>Mundo</p>;
       }
     }

Una restricci贸n de JSX es que siempre debes tener un elemento ra铆z:

const el = (
  <div>
    <p>Hola</p>
    <p>Mundo</p>
  </div>
);

Este es un patr贸n muy com煤n en las aplicaciones de React.

Mezclando JSX con JavaScript

Para mezclar c贸digo JavaScript en JSX utiliza llaves ({}):

const style = "active";
const title = "Hola Mundo";

<div className={style}>{title}</div>;

Una restricci贸n de JSX es que no puedes utilizar if, else, while o for.

Para agregar condicionales utiliza el operador ternario:

<div>{condition ? <h1>Hola Mundo</h1> : null}</div>

Para mostrar elementos de un arreglo o un objeto utiliza map:

const names = ["Jon", "Irma", "kEnAi"];

const jsx = (
  <ul>
    {names.map((name, index) => (
      <li key={index}>{name}</li>
    ))}
  </ul>
);

Estilos CSS inline en JSX

Es posible definir y utilizar estilos inline en JSX:

let styles = {
  borderColor: "#999",
};

const jsx = <div style={styles}>Hola mundo</div>;

Eventos del DOM en JSX

En JSX se utilizan los eventos est谩ndar del DOM como onclick, onchange, onkeydown, ... pero utilizando camelCase: onClick, onChange, onKeyDown, ...

<button onClick={alert("Hola")}></button>

F铆jate que utilizamos corchetes ({}) para escribir nuestro c贸digo JavaScript.

Tambi茅n podr铆amos pasar una funci贸n que es invocada cuando se genere el evento:

const saludar = () => alert("Hola!");

<button onClick={saludar}></button>;

F铆jate que no estamos invocando la funci贸n saludar, s贸lo la estamos pasando para que React la invoque cuando ocurra el evento.

馃敿 Regresar


Componentes

En React se introduce el concepto de componentes para crear la interfaz gr谩fica de nuestra aplicaci贸n.

Permiten separar el c贸digo y los elementos de la interfaz en peque帽as piezas independientes y reutilizables que estar谩n aisladas una de otras.

El objetivo es que cada componente sea independiente y encapsule su marcado, estilos y estado. De esa forma los componentes pueden ser reutilizables y la interfaz gr谩fica m谩s f谩cil de mantener y evolucionar.

Se le pueden pasar datos a un componente a trav茅s de algo llamado props y devuelven a React elementos que describen lo que debe verse en pantalla.

En React los datos fluyen de forma unidireccional, de componentes padres a componentes hijos.

React te permite definir componentes como clases o como funciones.

Tipos de Componentes

Como una clase que extiende de Component con un m茅todo render:

import React, { Component } from "react";

class Title extends Component {
  render() {
    return <h1>Hola mundo</h1>;
  }
}

O como una funci贸n que retorna lo que se va a renderizar:

const Title = () => {
  return <h1>Hola Mundo</h1>;
};

Utilizando un componente

Para utilizar un componente debes importarlo y despu茅s incluirlo en tu JSX como se muestra en el siguiente ejemplo:

import React from "react";
import Title from "./Title";

function App {
    return <Title />;
}

馃敿 Regresar


Propiedades

Son valores que recibe un componente hijo de uno padre. Se agrupan en un objeto llamado props, el cual puede recibir diferentes tipos de datos, como:

  • Strings
  • Numbers
  • Booleans
  • Arrays
  • Objects
  • Functions
  • React Elements
  • React Components

Las props son inmutables, es decir, son valores de s贸lo lectura, no se pueden modificar.

El componente las recibe como atributos que se pasan a trav茅s de JSX.

Por ejemplo, podemos pasar un atributo name al componente Welcome:

<Welcome name="Jon" />

<Welcome name="Irma" />

Si defines el componente en una clase, las props se reciben en el constructor de la clase:

class Welcome extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return <h1>{this.props.name}</h1>;
  }
}

Si defines el componente como una funci贸n, las props se reciben como un par谩metro de la funci贸n:

const Welcome = (props) => {
  return <h1>{props.name}</h1>;
};

馃敿 Regresar


Estado

El state son los valores internos que manejan la l贸gica y los datos de un componente, permite que 茅ste reaccione a cualquier cambio lo que har谩 que se vuelva a renderizar en la interfaz.

El estado tiene 3 caracter铆sticas importantes:

  1. Es inmutable.
  2. No se puede modificar directamente.
  3. Es as铆ncrono.

Para hacer cambios hay que hacer uso del m茅todo setState().

El estado de un componente no es accesible desde otro componente excepto de aquel que lo posee y lo asigna.

La propagaci贸n del estado fluye de forma unidireccional y descendiente (hacia abajo), esto significa que un componente padre puede pasar valores de su estado a componentes hijos que lo recibir谩n como propiedades.

En el momento que los valores del estado del padre sufran cambios esto causar谩 que tanto el padre como los hijos que recibieron esos valores como propiedades se rendericen nuevamente y reaccionen a dicho cambio.

Cada componente que se defina como una clase cuenta con un objeto para almacenar informaci贸n llamado state.

Cada vez que cambia el state React vuelve a renderizar (pintar) el componente en la vista.

class Welcome extends Component {
  constructor() {
    super();

    this.state = {
      title: "Hola Mundo",
    };
  }

  render() {
    return <h1>{this.state.title}</h1>;
  }
}

En este ejemplo estamos definiendo una componente Welcome que inicializa el estado con una llave title. En el m茅todo render estamos obteniendo el valor de esa llave con this.state.title.

Para cambiar el estado utiliza el m茅todo setState:

this.setState({
  title: "Hello World",
});

馃敿 Regresar


Renderizado condicional

En React, puedes crear distintos componentes que encapsulan el comportamiento que necesitas. Entonces, puedes renderizar solamente algunos de ellos, dependiendo del estado de tu aplicaci贸n.

El renderizado condicional en React funciona de la misma forma que lo hacen las condiciones en JavaScript. Puedes usar el condicional if o el operador ternario para crear elementos din谩micamente en base al valor del estado o las propiedades que recibe el componente.

Considera estos dos componentes:

function SaludoUsuario(props) {
  return <h1>隆Bienvenid@ nuevamente!</h1>;
}
function SaludoInvitado(props) {
  return <h1>Por favor, reg铆strate.</h1>;
}

Vamos a crear un componente Saludar que muestra cualquiera de estos componentes dependiendo si el usuario ha iniciado sesi贸n o no:

function Saludar(props) {
  const isLoggedIn = props.isLoggedIn;

  if (isLoggedIn) {
    return <SaludoUsuario />;
  }
  return <SaludoInvitado />;
}

ReactDOM.render(
  // Intentar cambiando isLoggedIn={true}:
  <Saludar isLoggedIn={false} />,
  document.getElementById("root")
);

Con el operador ternario el c贸digo quedar铆a de la siguiente manera:

function Saludar(props) {
  const isLoggedIn = props.isLoggedIn;

  return isLoggedIn ? <SaludoUsuario /> : <SaludoInvitado />;
}

ReactDOM.render(
  // Intentar cambiando isLoggedIn={true}:
  <Saludar isLoggedIn={false} />,
  document.getElementById("root")
);

馃敿 Regresar


Renderizado de elementos

Puedes hacer colecciones de elementos e incluirlos en JSX usando llaves {}.

Recorriendo los elementos de un array y usando la funci贸n map() de Javascript.

Por ejemplo:

const numeros = [1, 2, 3, 4, 5];
const listaElementos = numeros.map((numero) => <li>{numero}</li>);

Incluimos el array listaElementos dentro de un elemento <ul>, y lo renderizamos en el DOM:

ReactDOM.render(<ul>{listaElementos}</ul>, document.getElementById("root"));

Refactorizamos el ejemplo anterior en un componente que acepte un array de numeros e imprima una lista de elementos.

function ListaNumeros(props) {
  const numeros = props.numeros;
  const listaElementos = numeros.map((numero) => <li>{numero}</li>);
  return <ul>{listaElementos}</ul>;
}

const numeros = [1, 2, 3, 4, 5];
ReactDOM.render(
  <ListaNumeros numeros={numeros} />,
  document.getElementById("root")
);

Al ejecutar este c贸digo, ser谩s advertido que una key deber铆a ser proporcionada para elementos de lista.

Una 鈥key鈥 es un atributo especial de tipo string que debes incluir al crear listas de elementos.

Las keys ayudan a React a identificar que elementos han cambiado, son agregados, o son eliminados. Las keys deben ser dadas a los elementos dentro del array para darle una identidad estable.

La mejor forma de elegir una key es usando un string que identifique 煤nicamente a un elemento de la lista entre sus hermanos. Habitualmente vas a usar los IDs de tus datos como key.

Cuando no tengas IDs estables para renderizar, puedes usar como key el 铆ndice de los elementos del array de datos como 煤ltimo recurso.

Las keys usadas dentro de arrays deber铆an ser 煤nicas entre sus hermanos. Sin embargo, no necesitan ser 煤nicas globalmente. Podemos usar las mismas keys cuando creamos dos o m谩s arrays diferentes.

Entonces refactorizando nuestro c贸digo anterior quedar铆a as铆:

function ListaNumeros(props) {
  const numeros = props.numeros;
  const listaElementos = numeros.map((numero, indice) => (
    <li key={indice}>{numero}</li>
  ));
  return <ul>{listaElementos}</ul>;
}

const numeros = [1, 2, 3, 4, 5];
ReactDOM.render(
  <ListaNumeros numeros={numeros} />,
  document.getElementById("root")
);

馃敿 Regresar


Eventos

Manejar eventos en React es muy similar a manejar eventos en el DOM. Sin embargo existen algunas diferencias de sintaxis:

  • Los eventos de React se nombran usando camelCase, en vez de min煤sculas.
  • Con JSX pasas una funci贸n como el manejador del evento, en vez de un string.

Ejemplo, en HTML:

<button onclick="cambiarIdioma()">Cambiar idioma</button>

Ejemplo, en React:

<button onClick="{cambiarIdioma}">Cambiar idioma</button>

Otra diferencia es que en React no puedes retornar false para prevenir el comportamiento por defecto. Debes, expl铆citamente, llamar preventDefault.

Por ejemplo, en nuestro ejemplo del componente Welcome visto en el tema del Estado podemos cambiarlo para que cuando hagan click sobre el h1 cambie el texto. Para eso vamos a definir un m茅todo updateText que vamos a invocar cuando hagan click sobre el h1:

class Welcome extends Component {
  constructor() {
    super();

    this.state = {
      title: "Hola Mundo",
    };

    // tenemos que enlazar el m茅todo al contexto actual
    this.updateText = this.updateText.bind(this);
  }

  updateText() {
    this.setState({
      title: "Hello World",
    });
  }

  render() {
    return <h1 onClick={this.updateText}>{this.state.title}</h1>;
  }
}

馃敿 Regresar


Comunicaci贸n entre componentes

Tenemos 3 casos de comunicaci贸n entre los componentes de React:

  1. Comunicaci贸n entre un componente padre a uno hijo.
  2. Comunicaci贸n entre un componente hijo y su padre.
  3. Comunicaci贸n entre componentes no relacionados.

Comunicaci贸n entre un componente padre a uno hijo

脡ste es el caso m谩s natural en el mundo de React y se hace a trav茅s del paso de props de un componente padre a uno hijo.

import React, { Component } from "react";

class Padre extends Component {
  render() {
    return (
      <div>
        <Hijo mensaje="Mensaje para el hijo 1" />
        <Hijo mensaje="Mensaje para el hijo 2" />
      </div>
    );
  }
}

function Hijo(props) {
  return <h2>{props.mensaje}</h2>;
}

export default Padre;

Comunicaci贸n entre un componente hijo y su padre

Cuando tenemos la necesidad de que un componente hijo mande datos a su padre los podemos hacer a traves de los eventos, simplemente pasamos una funci贸n como prop del componente padre al componente hijo, y 茅ste ejecutar谩 la funci贸n .

En este ejemplo, cambiaremos el estado del componente padre pasando una funci贸n al componente hijo e invocando esa funci贸n dentro del componente hijo.

import React, { Component } from "react";

class Padre extends Component {
  constructor(props) {
    super(props);
    this.state = { contador: 0 };

    this.incrementarContador = this.incrementarContador.bind(this);
  }

  incrementarContador(e) {
    //el contexto del evento proviene del Hijo
    this.setState({ contador: this.state.contador++ });
  }

  render() {
    return (
      <div>
        <Hijo
          mensaje="Mensaje para el hijo 1"
          incrementarContador={incrementarContador}
        />
        <Hijo
          mensaje="Mensaje para el hijo 2"
          incrementarContador={incrementarContador}
        />
      </div>
    );
  }
}

function Hijo(props) {
  return (
    <div>
      <h2>{props.mensaje}</h2>
      <button onClick={props.incrementarContador}>+</button>
    </div>
  );
}

export default Padre;

Comunicaci贸n entre componentes no relacionados

Si los componentes no tienen una relaci贸n padre-hijo o est谩n relacionados, pero est谩n demasiado lejos, como por ejemplo, un bisnieto o tataranieto, tenemos que crear un mecanismo de observaci贸n y/o suscripci贸n para la comunicaci贸n entre dichos componentes.

Al menos existen 3 patrones para hacer esto.

  1. Patr贸n Emisor de eventos / Destino / Despachador : los oyentes deben hacer referencia a la fuente para suscribirse.
  2. Patr贸n Publicaci贸n / Suscripci贸n: no necesita una referencia espec铆fica a la fuente que desencadena el evento, hay un objeto global accesible en todas partes que maneja todos los eventos.
  3. Patr贸n Se帽ales: similar al Emisor de Eventos, pero aqu铆 no usa cadenas aleatorias. Cada objeto que podr铆a emitir eventos debe tener una propiedad espec铆fica con ese nombre. De esta manera, se sabe exactamente qu茅 eventos puede emitir un objeto.
  4. Portales: proporcionan una opci贸n de primera clase para renderizar hijos en un nodo DOM que existe por fuera de la jerarqu铆a del DOM del componente padre.

Puedes encontrar m谩s informaci贸n al respecto en este enlace.

Otra manera de compartir datos entre componentes sin que tengan una relaci贸n padre-hijo es compartiendo un estado global accesible para todos los componentes de nuestra aplicaci贸n, para ello podr铆amos usar 2 opciones:

  1. Redux: librer铆a externa a React para el manejo del estado.
  2. Context: un API interna de React que provee una forma de pasar datos a trav茅s del 谩rbol de componentes sin tener que pasar props manualmente en cada nivel. Esta API la retomaremos cuando veamos el tema de Hooks.

馃敿 Regresar


Ciclo de Vida

Son m茅todos que se ejecutan autom谩ticamente en un Componente de Clase, ocurren en 3 fases:

  1. Montaje.
  2. Actualizaci贸n.
  3. Desmontaje

Montaje

Estos m茅todos se ejecutan cuando se crea un componente y se inserta en el arbol del DOM.

  • constructor(): Se ejecuta al crear la instancia del componente, en el constructor puedes inicializar el estado y enlazar manejadores de eventos.
  • render(): Es el 煤nico m茅todo requerido, cuando se ejecuta, examina el estado y las propiedades y dibuja el componente en el 谩rbol del DOM.
  • componentDidMount(): Se invoca inmediatamente despu茅s de que un componente se ha insertado al 谩rbol del DOM. Es 煤til para ejecutar suscripciones o peticiones as铆ncronas a API's, bases de datos, servicios, etc.

Actualizaci贸n

Estos m茅todos son ejecutados por cambios en el estado o las propiedades de los componentes.

  • render(): redibuja el componente cuando detecta cambios en el estado o las propiedades del componente.
  • componentDidUpdate(): Se ejecuta inmediatamente despu茅s de que la actualizaci贸n del estado o las propiedades sucede, al igual que componenDidMount es un m茅todo ideal para hacer peticiones externas.

Desmontaje

Estos m茅todos son ejecutados una vez que el componente ha sido eliminado del 谩rbol del DOM.

  • componentWillUnmount(): Se ejecuta antes de destruir el componente del 谩rbol del DOM, es un m茅todo 煤til para hacer tareas de limpieza.

馃敿 Regresar


Hooks

Los Hooks son una nueva incorporaci贸n a partir de React 16.8.0, que nos permiten "enganchar" el estado y el ciclo de vida en componentes basados en funciones.

驴Por qu茅 se crearon los Hooks?

Las clases confunden a las personas y a las m谩quinas.

Entender la estructura y reglas que implican crear una clase puede ser una curva de aprendizaje lenta y requerir de ciertos conceptos, como el manejo de this en JavaScript, por el contrario las funciones son muy f谩ciles de entender y manipular incluso para personas que van comenzando.

A las m谩quinas tampoco les gusta las clases ya que no minifican tan bien como las funciones, esto significa que nuestro c贸digo ocupar谩 m谩s texto y por ende m谩s espacio de almacenamiento.

Preguntas frecuentes

  • 驴Los hooks hacen que mi aplicaci贸n sea m谩s r谩pida? NO.
  • 驴Los hooks hacen algo que un Componente de Clase no pueda hacer? NO.
  • 驴Los Componentes de Clase van a desaparecer? NO.
  • 驴Mi conocimiento del estado, las propiedades y los eventos ser谩n obsoleto ahora con hooks? NO.
  • 驴Debo reescribir todas mis aplicaciones React, ahora con hooks? Probablemente NO.
  • 驴Debo implementar hooks en mi pr贸ximo proyecto? Probablemente S脥.

Tipos de Hooks

  • B谩sicos (en el 100% de tus proyectos):
    • useState.
    • useEffect.
  • Avanzados (tal vez no en todos tus proyectos):
    • useContext.
    • useRef.
    • useReducer.
    • useCallback.
    • useMemo.

Puedes ver toda la lista de hooks disponibles en la documentaci贸n de React.

En este art铆culo explicaremos los hooks:

  • useState.
  • useEffect.

useState

Permite manipular el estado de un componente funcional, se comporta como el objeto state y a la funci贸n this.setState de los componentes de clase.

Para usarlo, debemos importarlo desde la librer铆a de React.

import React, { useState } from "react";

Ahora, en nuestro componente funcional, vamos a inicializar el hook, para ello asignaremos mediante la destructuraci贸n de arreglos 2 elementos:

  1. El valor del estado y,
  2. Un m茅todo para actualizarlo

Adicionalmente le pasaremos como par谩metro el valor inicial del estado al m茅todo useState.

import React, { useState } from "react";

export default function Componente() {
  const [valor, setValor] = useState(0);

  return <span>El valor del componente es {valor}</span>;
}

Para actualizar el estado tenemos que utilizar el m茅todo resultante de la destructuraci贸n de useState y pasarle el nuevo valor.

import React, { useState } from "react";

export default function Componente() {
  const [valor, setValor] = useState(0);
  return (
    <div>
      <span>El valor del componente es {valor}</span>
      <button onClick={() => setValor(valor + 1)}>Aumentar valor</button>
    </div>
  );
}

Un detalle del estado en los Hooks, es que no debe ser tratado como un objeto como en los componentes de clases, si necesitas m谩s de un valor cada uno debe ser almacenado en una variable diferente y usar la destructurci贸n de useState.

import React, { useState } from "react";

export default function Componente() {
  const [valor, setValor] = useState(0);
  const [valor2, setValor2] = useState("Hola Mundo");
  const [valor3, setValor3] = useState(true);

  return (
    <div>
      <span>El valor del componente es {valor}</span>
      <button onClick={() => setValor(valor + 1)}>Aumentar valor</button>
    </div>
  );
}

useEffect

Permite hacer uso del ciclo de vida en un componente funcional. Usar useEffect equivale a la combinaci贸n de los m茅todos:

  • componentDidMount() (montaje).
  • componentDidUpdate() (actualizaci贸n).
  • componentWillUnmount() (desmontaje).

useEffect recibe como par谩metro una funci贸n que se ejecutar谩 cada vez que nuestro componente se renderice, ya sea por cambios del estado o las propiedades.

Para usarlo, debemos importarlo desde la librer铆a de React.

import React, { useEffect } from "react";

Para a帽adir un efecto que se ejecutar谩 cada vez que nuestro componente se renderice, se debe pasar como par谩metro una funci贸n al hook useEffect misma que se ejecutar谩 al renderizarse el componente.

import React, { useEffect } from "react";

export default function Efecto() {
  useEffect(function () {
    console.log("Me he renderizado!!!");
  });

  return <span>Este es un ejemplo del hook useEffect.</span>;
}

Con useEffect tambi茅n podemos suscribirnos y desuscribirnos a eventos, temporizadores, servicios, API's, etc.

Para ello hay que escribir el c贸digo de la suscripci贸n en el cuerpo de la funci贸n de useEffect y para evitar problemas de rendimiento o aumento indiscriminado de la memoria y recursos de nuestra aplicaci贸n retornar en una funci贸n el c贸digo que desuscriba o cancele lo que se ejecuto en el cuerpo de la funci贸n.

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

export default function ScrollYNavegador() {
  const [scrollY, setScrollY] = useState(0);

  useEffect(() => {
    //Creamos una funci贸n para actualizar el estado
    const actualizarScrollY = () => {
      let scrollY = window.pageYOffset;
      console.log(`scrollY: ${scrollY}`);
      setScrollY(scrollY);
    };
    //Actualizamos el scroll al montar el componente
    actualizarScrollY();
    //Nos suscribimos al evento scroll de window
    window.addEventListener("scroll", actualizarScrollY);

    //Devolvemos una funci贸n para desuscribir el evento
    return () => {
      window.removeEventListener("scroll", actualizarScrollY);
    };
  });

  return (
    <div>
      <span>ScrollY del Navegador: {scrollY}px</span>
    </div>
  );
}

Por defecto los efectos se ejecutan cada vez que se realiza un renderizado, si queremos evitar actualizaciones innecesarias o indiscriminadas podemos pasarle un segundo par谩metro al hook.

El par谩metro debe ser un array con todos los valores de los que depender谩 el efecto, de forma que s贸lo se ejecutar谩 cuando ese valor cambie.

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

export default function ScrollYNavegador() {
  const [scrollY, setScrollY] = useState(0);

  useEffect(() => {
    //Creamos una funci贸n para actualizar el estado
    const actualizarScrollY = () => {
      let scrollY = window.pageYOffset;
      console.log(`scrollY: ${scrollY}`);
      setScrollY(scrollY);
    };
    //Actualizamos el scroll al montar el componente
    actualizarScrollY();
    //Nos suscribimos al evento scroll de window
    window.addEventListener("scroll", actualizarScrollY);

    //Devolvemos una funci贸n para desuscribir el evento
    return () => {
      window.removeEventListener("scroll", actualizarScrollY);
    };
  }, [scrollY]);

  return (
    <div>
      <span>ScrollY del Navegador: {scrollY}px</span>
    </div>
  );
}

Si le pasamos un array vac铆o, eso har谩 que el efecto no dependa de ning煤n valor, por lo que s贸lo se ejecutar谩 al montarse y desmontarse el componente.

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

export default function ScrollYNavegador() {
  const [scrollY, setScrollY] = useState(0);

  useEffect(() => {
    //Creamos una funci贸n para actualizar el estado
    const actualizarScrollY = () => {
      let scrollY = window.pageYOffset;
      console.log(`scrollY: ${scrollY}`);
      setScrollY(scrollY);
    };
    //Actualizamos el scroll al montar el componente
    actualizarScrollY();
    //Nos suscribimos al evento scroll de window
    window.addEventListener("scroll", actualizarScrollY);

    //Devolvemos una funci贸n para desuscribir el evento
    return () => {
      window.removeEventListener("scroll", actualizarScrollY);
    };
  }, []);

  return (
    <div>
      <span>ScrollY del Navegador: {scrollY}px</span>
    </div>
  );
}

馃敿 Regresar


Aprende m谩s

Ve mi Curso

馃敿 Regresar