React Workshop

Introducción

Bueno, arranquemos viendo los requerimientos para correr todo:

Bueno, como los devs de facebook son gente copada, tienen un repo con webpack y react todo configurado y lindo para empezar a laburar rápido; así que, una vez que tengamos NodeJS instalado, abrimos la línea de comando (Bash, Terminal, CMD, CMDer, iTerm, etc.) y nos posicionamos en la carpeta donde queramos laburar y tipeamos los siguientes comandos:

npx create-react-app reactworkshop --scripts-version react-scripts@^2
cd reactworkshop
npm start

El primer comando nos crea una carpeta 'ReactWorkshop', clona ahí adentro lo de este repo Create-React-App e instala los paquetes necesarios para trabajar, luego entramos al directorio creado y con el último comando corremos un servidor local con hot reloading (actualización automática de los cambios que hagamos). Este servidor corre por defecto en http://localhost:3000. Debería abrirse una pestaña en nuestro navegador por defecto con esta dirección, si no lo hace pueden hacerlo manualmente. Y tengan en cuenta que para frenar el servidor estando en la línea de comando hay que presionar Ctrl + C.

Si no hubo problemas, ya tenemos nuestro primer componente que no hicimos nosotros andando! Yay!

Empezando a trabajar

Ahora abrimos la carpeta de nuestro proyecto en nuestro IDE o editor favorito (el mío es VS Code) y vamos al archivo App.js, ese es nuestro componente de entrada a la web app que estamos haciendo, el componente donde van a vivir nuestros demás componentes. El punto de entrada a la aplicación por medio de React es el archivo index.js, vamos a analizarlos:

index.js

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

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

¿Qué vemos acá? Bueno, ignorando las líneas sobre Service Workers (las eliminé, no vamos a tratar ese tema en este workshop), vemos que usando imports de ES6 (cosas nuevas de Javascript) traemos React para tener React a mano (duh), ReactDOM para actuar de intermediario entre nuestra app y el DOM, estilos en el index.css y algo re loco y nuevo, nos traemos el componente App que es el componente principal donde van a vivir los demás componentes nuestra aplicación. Algo que quizás me olvidé de contar es que TODO en React es un componente, sí, todo.

En el último renglón usamos un método de ReactDOM para indicarle que tiene que renderizar el componente App en el elemento del DOM que tenga como id root. Este elemento es un div y lo vamos a encontrar en el archivo index.html dentro de la carpeta /public.

Pasemos a chusmear nuestro componente principal:

App.js

import React, { Component } from 'react'
import logo from './logo.svg'
import './App.css'

class App extends Component {
  render() {
    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>
    )
  }
}

export default App

Wow, muchas cosas nuevas por acá. Como diría Jack, vamos por partes. Antes que nada, como convención los componentes comienzan con letra mayúscula, siguiendo con lo nuestro vemos que tenemos otra forma de importar un solo miembro de cierto módulo, usando lo que se llama named import (En el link pueden leer más al respecto). Haciendo import React, { Component } from "react";, importamos React y el módulo Component para luego indicar que App va a ser un Component class App extends Component. Esto está hecho para simplificar el código a como lo vemos nosotros, es lo mismo no importar Component y escribir class App extends React.Component 🤷‍♀️ pero bueno, nos sirve para aprender que existen los named imports. Este tipo de componentes se llaman "Componentes de Clase" y tienen lo que se llama state (estado) por defecto, si no necesitamos usar el state, podemos usar lo que se llama "Componente Funcional". Si no entendés todavía lo que es el state, tranqui, lo vamos a ver más adelante, paciencia :) Nuestro componente App como Componente Funcional quedaría de la siguiente forma:

import React from 'react'
import logo from './logo.svg'
import './App.css'

const App = () => (
  <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>
)

export default App

Como vemos, estamos guardando una arrow function en App (de ahí su nombre de "Funcional") y hacemos un return (implícito) de nuestro JSX. Esta sintaxis la vamos a usar en los componentes que reciban props y que no necesiten tener un state. Sí, ya sé, cada vez sumamos más conceptos, ya los vamos a ver, chillax. Dejemos a App tranquilo como Componente de Clase mejor, ya vamos a ver por qué.

Si seguimos vemos que usar imágenes en svg es tan simple como importarla y usarla en el atributo (prop, en realidad, ya lo vas a entender) de nuestra img. Lo raro es que está entre llaves, esto es porque estamos usando JSX y cuando ponemos algo entre llaves, estamos indicando que vamos a utilizar Javascript. En este caso, le decimos que usamos la imagen importada en logo, Webpack se encarga de esto, que ya viene todo configurado y lindo. De esta forma podemos importar JPG, PNG, GIF, BMP y SVG.

Bueno, debo estar aburriendo con tanto para leer, vamos a crear nuestro primer componente! Emoción

Lo que vamos a hacer es:

  1. Escribir un componente con un párrafo que diga "Hola Mundo!" (va a ser un Componente Funcional)
  2. Insertarlo dentro de nuestro componente principal App
  3. Una vez que lo veamos funcionando, lo pasamos a otro archivo para tener nuestros componentes aislados y ver qué tan simple es separar en componentes

Bueno, vamos a tipear: Hagamos nuestro componente funcional, vamos a elegir un nombre, por ejemplo, Saludo (recordá que el nombre del componente debe empezar con mayúscula), entonces hacemos:

const Saludo = () => <p>Hola Mundo!</p>

Y así de simple tenemos un componente nuevo, en un solo renglón 😜 (obvio que es un componente simple, después se va a ir complejizando la cosa). Este renglón vamos a tener que escribirlo entre los imports y la declaración de nuestro componente App.

import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";

//Acá va nuestro nuevo componente
const Saludo = () => <p>Hola Mundo!</p>;

class App extends Component {
/* [...] */

Genial, si guardamos el archivo en este momento vemos que nuestra web app se actualiza automáticamente y en la consola React nos chilla porque tenemos definido el componente pero no lo estamos utilizando. Sabemos que adentro de Saludo vive nuestro componente que definimos, ahora cómo lo usamos?: Donde querramos que vaya nuestro componente (en JSX), escribimos <Saludo />. Listo. No está buenísimo?

Nuestro componente App quedaría así:

import React, { Component } from 'react'
import logo from './logo.svg'
import './App.css'

const Saludo = () => <p>Hola Mundo!</p>

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          {/* Nuestro componente recién creado */}
          <Saludo />
          <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>
    )
  }
}

export default App

Recuerden que cada componente de React puede retornar solamente UN elemento y en JSX los elementos pueden cerrarse en la misma línea si es que no tienen children, por ejemplo, nuestro componente nuevo podemos escribirlo tanto como lo hicimos recién o de la siguiente forma:

<Saludo>{/* Acá irían los hijos o children */}</Saludo>

Ya tenemos nuestro nuevo componente dentro de su componente padre (en el árbol de jerarquías, queda App como componente padre y Saludo como su hijo), ahora vamos a guardarlo en un archivo aparte para entender más el tema de la componentización (fua, qué palabra). Empezamos por crear una carpeta /components dentro de /src donde va a vivir nuestro nuevo componente y dentro de esa carpeta /src/components creamos un archivo, Saludo.js. En este nuevo archivo empezamos a tipear:

  • Primero importamos React import React from "react";
  • Pasamos nuestro componente funcional a este archivo: const Saludo = () => <p>Hola Mundo!</p>;
  • Exportamos nuestro componente para que pueda ser utilizado fuera de este archivo: export default Saludo;

Listo, guardamos lo que hicimos y vamos a editar nuestro componente padre App para traer nuestro nuevo componente:

  • Borramos la línea donde definíamos a nuestro componente Saludo: const Saludo = () => <p>Hola Mundo!</p>;
  • Importamos nuestro componente desde el archivo recién creado (escribimos esta línea donde estaba la línea que recién borramos): import Saludo from "./components/Saludo";

Guardamos y si todo sale bien, debería estar todo funcionando igual que hasta recién.

Nuestros componentes deberían quedar así:

App.js

(Limpié un poco para que quede solamente nuestro nuevo componente)

import React, { Component } from 'react'
import './App.css'

import Saludo from './components/Saludo'

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <Saludo />
        </header>
      </div>
    )
  }
}

export default App

Saludo.js

import React from 'react'

const Saludo = () => <p>Hola Mundo!</p>

export default Saludo

Ya hiciste tu primer componente, felicitaciones!!!! 🎉🎉🎉🎉🎉🎉

Ahora necesitamos aprender Props, State y algunas cosas más de componentes para poder seguir, no me odies, yo sé que es mucha teoría.

© 2021 - MIT License