Skip to content

Fundamentos de React JS

Objetivos

  • ¿Qué es React?
  • create-react-app vs vite.js
  • JSX
  • Introducción a componentes
  • Introducción a Hooks

WARNING

Extensiones VSCode

Recursos

⭐ Videos Premium ⭐

Esta sección es parte del curso en Udemy. Si quieres acceder a ella, puedes comprar el curso en Udemy: React + Firebase by bluuweb.

¿Qué es React?

  • React es una biblioteca Javascript para crear interfaces de usuario.
  • React no es un framework (a diferencia de Angular o Vue, que tienen más opiniones).
  • React es un proyecto de código abierto creado por Facebook.
  • Está basado en componentes.

getting-started-with-react

Uno de los aspectos más importantes de React es el hecho de que puede crear componentes, que son como elementos HTML personalizados y reutilizables, para construir interfaces de usuario de manera rápida y eficiente. React también agiliza la forma en que se almacenan y manejan los datos, utilizando el estado y los accesorios.

Requisitos

  • node js: es un entorno en tiempo de ejecución multiplataforma, de código abierto, para la capa del servidor (pero no limitándose a ello) basado en el lenguaje de programación JavaScript.
  • npm: NPM (Node Package Manager) es un gestor de paquetes desarrollado en su totalidad bajo el lenguaje JavaScript por Isaac Schlueter, a través del cual podemos obtener cualquier librería con tan solo una sencilla línea de código, lo cual nos permitirá agregar dependencias de forma simple, distribuir paquetes y administrar eficazmente tanto los módulos como el proyecto a desarrollar en general. fuente

¿Qué es un módulo?

  • Un módulo no es nada más que una unidad de código organizado en archivos o directorios, la cual puede ser exportada con facilidad para poder reutilizarse en otras partes de la aplicación. fuente
  • External modules: Son, en esencia, los paquetes de terceros distribuidos a través de npm (aunque pueden provenir de otros repositorios). Estos paquetes se instalan como dependencias y, aunque aportan funcionalidad a la aplicación, no deben incluirse en el repositorio ya que no son parte de la misma.

Instalación

  • Vite.js
  • CRA create react app

Vite

  • Vite web oficial: Vite se define como una herramienta de frontend que te ayudará a crear proyectos (sin atarte a ningún framework concreto) y que su desarrollo y construcción final sea lo más sencilla posible.
  • Está desarrollada por Evan You, el creador de Vue.
  • Actualmente, Vite soporta tanto proyectos vanilla (sin utilizar frameworks), como proyectos utilizando Vue, React, Preact o Lit-element (tanto en versión Javascript, como Typescript). Fuente
  • Templates
  • Comunidad DEV
sh
npm create vite@latest

create-react-app

  • create-react-app Afortunadamente, Facebook ha creado la aplicación Create React App, un entorno que viene preconfigurado con todo lo necesario para crear una aplicación React.
  • Creará un servidor de desarrollo en vivo.
  • No es necesario instalar ni configurar herramientas como webpack o Babel. Están preconfigurados y ocultos para que pueda concentrarse en el código.
  • Ventaja: enfocarse en el código, no en las herramientas de compilación.
npx create-react-app my-app
cd my-app
npm start

npx

  • Npx es una herramienta de cli que nos permite ejecutar paquetes de npm, los busca en su servidor y lo ejecuta en nuestra máquina.
  • Si usas npx no tienes que instalar paquetes de forma global.
  • Busca siempre la última versión.

WARNING

Si ha instalado previamente create-react-app globalmente a través de: npm install -g create-react-app, le recomendamos que desinstale el paquete usando npm uninstall -g create-react-app o yarn global remove create-react-app para asegurarse de que npx siempre usa la última versión.

CRA vs Vite

  • Vite y CRA no son tan diferentes como podría pensar. Básicamente, hacen más o menos lo mismo, que es servir a un servidor de desarrollo local y agrupar códigos para la producción.
  • La principal diferencia que notará es cómo se sirve el código en el desarrollo y qué módulos son compatibles.
  • Vite no necesita agrupar la aplicación completa o transpilar los módulos y el código antes de iniciar un servidor de desarrollo; la transpilación se realiza bajo demanda, lo que la hace significativamente más rápida que CRA.
  • Sigue estudiando aquí

JSX: JavaScript + XML

  • Como ha visto, hemos estado usando lo que parece HTML en nuestro código React, pero no es HTML del todo. Esto es JSX , que significa JavaScript XML.
  • El uso de JSX no es obligatorio para escribir React.
  • Debajo del capó, se está ejecutando createElement, lo que toma la etiqueta, las propiedades y los elementos secundarios del componente y muestra la misma información.
  • JSX está más cerca de JavaScript, no de HTML, por lo que hay algunas diferencias clave a tener en cuenta al escribirlo.
    • className se usa en lugar de class para agregar clases CSS, ya que class es una palabra clave reservada en JavaScript.
    • Las propiedades y métodos en JSX son camelCase.
    • Las etiquetas de cierre automático deben terminar en una barra inclinada,
      Ej. <img />
    • Su componente tampoco puede devolver varias etiquetas JSX. Tienes que envolverlos en un padre compartido, como un envoltorio <div>...</div> vacío o: <>...</>

Las expresiones de JavaScript también se pueden incrustar dentro de JSX usando llaves, incluidas variables, funciones y propiedades.

jsx
const App = () => {
  const title = "Mi primero proyecto con React.js";
  return (
    <div className="container">
      <h1 className="text-primary">{title}</h1>
    </div>
  );
};

export default App;
jsx
const App = () => {
  const title = "Mi primero proyecto con React.js";
  const classColors = {
    primary: "text-primary",
    info: "text-info",
  };
  return (
    <div className="container">
      <h1 className={classColors.primary}>{title}</h1>
      <p className={classColors.info}>Lorem ipsum dolor sit.</p>
    </div>
  );
};

export default App;

Componentes

  • Las aplicaciones React están hechas de componentes .
  • Un componente es una parte de la IU (interfaz de usuario) que tiene su propia lógica y apariencia.
  • Un componente puede ser tan pequeño como un botón o tan grande como una página entera.
  • Los componentes de React son funciones de JavaScript:
jsx
const MyButton = () => {
  return <button>i'am a button</button>;
};

const App = () => {
  const title = "Mi primero proyecto con React.js";
  return (
    <div className="container">
      <h1 className="text-primary">{title}</h1>
      <MyButton />
    </div>
  );
};

export default App;

componentes siempre en Mayúsculas

Fíjate que <MyButton /> empieza con mayúscula. Así es como sabes que es un componente React. Los nombres de los componentes de React siempre deben comenzar con una letra mayúscula, mientras que las etiquetas HTML deben estar en minúsculas.

Renderizado condicional

  • 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.
jsx
const MyButton = () => {
  return <button>i'am a button</button>;
};

const UserMessage = () => {
  return <h2>Bienvenido usuario</h2>;
};

const App = () => {
  const title = "Mi primero proyecto con React.js";
  const user = true;
  return (
    <div className="container">
      <h1 className="text-primary">{title}</h1>
      <MyButton />
      {user ? <UserMessage /> : "Offline"}
    </div>
  );
};

export default App;

¿Qué pasa si omitimos 'else'?

  • Podemos utilizar el operador lógico AND (&&)
  • Este operador lógico compara dos expresiones.
  • Si la primera se evalúa como "true", la sentencia devolverá el valor de la segunda expresión.
  • Si la primera expresión se evalúa como "false", la sentencia devolverá el valor de la primera expresión, en nuestro caso false.
jsx
{
  user && <UserMessage />;
}

Listas y keys

jsx
const App = () => {
  const fruts = ["🍐", "🍌", "🍎"];
  return (
    <div className="container">
      <ul>
        {fruts.map((frut, index) => {
          return <li key={index}>{frut}</li>;
        })}
      </ul>
    </div>
  );
};

export default App;

TIP

  • React usa el key prop para crear una relación entre el componente y el elemento DOM.
  • La biblioteca utiliza esta relación para determinar si el componente debe volver a renderizarse o no.
  • No se recomienda utilizar el índice de la matriz como key si sabe que la matriz no será estática.
  • Si key es un índice, reordenar un elemento en la matriz lo cambia. Entonces React se confundirá y volverá a renderizar el elemento incorrecto.
  • fuente

props

  • Se utiliza para enviar información al componente anidado.
  • La información que transmites de esta manera se llama props.
jsx
const ItemFrut = (props) => {
  return <li>{props.frut}</li>;
};

const App = () => {
  const fruts = ["🍐", "🍌", "🍎"];
  return (
    <div className="container">
      <ul>
        {fruts.map((frut, index) => {
          return (
            <ItemFrut
              key={index}
              frut={frut}
            />
          );
        })}
      </ul>
    </div>
  );
};

export default App;

Con PropsTypes podemos validar los props que recibe un componente:

jsx
import PropTypes from "prop-types";

const ItemFrut = (props) => {
  return <li>{props.frut}</li>;
};

ItemFrut.propTypes = {
  frut: PropTypes.string.isRequired,
};

EsLint

  • ESLint es una herramienta de linting para JavaScript. El linting es un proceso mediante el cual se analiza el código fuente de un programa en busca de posibles errores, problemas de estilo o prácticas desaconsejadas.
  • ESLint permite detectar errores comunes en el código, como variables no utilizadas, funciones no definidas, declaraciones duplicadas, entre otros.

.eslintrc.cjs

El archivo .eslintrc.cjs es un archivo de configuración de ESLint en formato CommonJS (CJS).

env

La propiedad node: true en la sección env de un archivo de configuración de ESLint indica que el código que está siendo analizado por ESLint se ejecutará en un entorno de Node.js. Esto le permite a ESLint reconocer y aplicar las reglas y configuraciones específicas de Node.js durante el proceso de linting.

js
env: { browser: true, es2020: true, node: true },

react/props-types off

js
module.exports = {
  // ...otras configuraciones...

  rules: {
    // ...otras reglas...
    "react/prop-types": "off", // Desactivar validación de PropTypes
  },
};

PropTypes

  • En React, PropTypes es una característica que permite especificar el tipo de las props (propiedades) que se pasan a los componentes.
  • PropTypes proporciona una forma de documentar y validar las props que se esperan en un componente, lo que ayuda a evitar errores y facilita el desarrollo y mantenimiento del código.

Tipos comunes de PropTypes:

  • number: Valida que la prop sea un número.
  • bool: Valida que la prop sea un valor booleano (true o false).
  • array: Valida que la prop sea un array.
  • object: Valida que la prop sea un objeto.
  • symbol: Valida que la prop sea un símbolo.
  • node: Valida que la prop pueda ser cualquier cosa que se pueda renderizar en React (elemento React, cadena de texto, número, fragmento, etc.).
  • element: Valida que la prop sea un único elemento React (es decir, no un fragmento ni una cadena de texto).
  • instanceOf(Constructor): Valida que la prop sea una instancia de una clase específica.
  • oneOf([val1, val2, ...]): Valida que la prop sea uno de los valores proporcionados en un array.
  • oneOfType([type1, type2, ...]): Valida que la prop cumpla con al menos uno de los tipos de datos especificados en un array.
  • arrayOf(type): Valida que la prop sea un array que contenga elementos del tipo especificado.
  • objectOf(type): Valida que la prop sea un objeto cuyos valores sean del tipo especificado.

Ejemplo:

jsx
import PropTypes from "prop-types";

const MyButton = ({ text, handleClick }) => {
  return <button onClick={handleClick}>{text}</button>;
};

MyButton.propTypes = {
  text: PropTypes.string.isRequired,
  handleClick: PropTypes.func.isRequired,
};

const App = () => {
  const handleClick = () => {
    console.log("clicked");
  };

  return (
    <div>
      <MyButton
        text="text"
        handleClick={handleClick}
      ></MyButton>
    </div>
  );
};
export default App;

Práctica props

  • Intenta hacer lo mismo pero con el componente UserMessage
  • Puedes utilizar la desestructuración de JS. más info aquí

Opción #01:

jsx
const UserMessage = ({ user }) => {
  if (user) return <h2>Bienvenido</h2>;

  return <h2>Offline</h2>;
};

Opción #02:

jsx
export default ({ user }) => <h2>{user ? "Bienvenido" : "offline"}</h2>;

Manejando eventos

  • eventos
  • 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.
jsx
const MyButton = () => {
  const handleClick = () => {
    console.log("me diste click");
  };

  return <button onClick={handleClick}>i'am a button</button>;
};

Con parámetros:

jsx
const MyButton = () => {
  const handleClick = (name) => {
    console.log("me diste click: ", name);
  };

  return <button onClick={() => handleClick("🍎")}>i'am a button</button>;
};

Componentes (modularizar)

  • components
  • Los componentes permiten separar la interfaz de usuario en piezas independientes, reutilizables y pensar en cada pieza de forma aislada.

components/MyButton.jsx

jsx
const MyButton = () => {
  const handleClick = (name) => {
    console.log("me diste click: ", name);
  };

  return <button onClick={() => handleClick("🍎")}>i'am a button</button>;
};

export default MyButton;

App.jsx

jsx
import MyButton from "./components/MyButton";
const App = () => {
  return (
    <div className="container">
      <h1 className="text-primary">{title}</h1>
      <MyButton />
    </div>
  );
};

export default App;

Práctica components

  • Intenta llevar todo a componentes modularizados.
  • ./components/MyButton.jsx
  • ./components/UserMessage.jsx
  • ./components/fruts/ListFruts.jsx
  • ./components/fruts/ItemFrut.jsx
jsx
import MyButton from "./components/MyButton";
import UserMessage from "./components/UserMessage";
import ListFruts from "./components/fruts/ListFruts";

const App = () => {
  const title = "Mi primero proyecto con React.js";
  const user = false;

  return (
    <div className="container">
      <h1 className="text-primary">{title}</h1>
      <MyButton />
      <UserMessage user={user} />
      <ListFruts />
    </div>
  );
};

export default App;

Fragmentos

  • fragment: Un patrón común en React es que un componente devuelva múltiples elementos. Los Fragmentos te permiten agrupar una lista de hijos sin agregar nodos extra al DOM.
jsx
import MyButton from "./components/MyButton";
import UserMessage from "./components/UserMessage";
import ListFruts from "./components/fruts/ListFruts";
import React from "react";

const App = () => {
  const title = "Mi primero proyecto con React.js";
  const user = false;

  return (
    <React.Fragment>
      <h1 className="text-primary">{title}</h1>
      <MyButton />
      <UserMessage user={user} />
      <ListFruts />
    </React.Fragment>
  );
};

export default App;
jsx
import MyButton from "./components/MyButton";
import UserMessage from "./components/UserMessage";
import ListFruts from "./components/fruts/ListFruts";

const App = () => {
  const title = "Mi primero proyecto con React.js";
  const user = false;

  return (
    <>
      <h1 className="text-primary">{title}</h1>
      <MyButton />
      <UserMessage user={user} />
      <ListFruts />
    </>
  );
};

export default App;

Estado

  • El estado le permite a los componentes de React cambiar su salida a lo largo del tiempo en respuesta a acciones del usuario, respuestas de red y cualquier otra cosa.
  • state
  • Para hacer cambios vamos a utilizar un hook.

Hooks

¿Qué pasa si hago esto? import CounterExample from "./components/CounterExample";

jsx
export default () => {
  let counter = 0;

  const handleClickIncrement = () => {
    counter++;
    console.log(counter);
  };

  return <button onClick={handleClickIncrement}>Counter: {counter}</button>;
};
  • Nada le indica a React que tenemos que volver a renderizar para pintar nuevamente button.
  • Necesitamos un Hook que modifique el estado. (ahora con hooks es más fácil)

hooks

  • hooks
  • Los Hooks son funciones que te permiten “enganchar” el estado de React y el ciclo de vida desde componentes de función.
  • Los hooks no funcionan dentro de las clases — te permiten usar React sin clases.
  • React proporciona algunos Hooks incorporados como useState.
  • También puedes crear tus propios Hooks para reutilizar el comportamiento con estado entre diferentes componentes.

useState

js
import { useState } from "react";

export default () => {
  const [counter, setCounter] = useState(0);

  const handleClickIncrement = () => {
    setCounter(counter + 1);
    //setCounter((prevCounter) => prevCounter + 1);
  };

  return <button onClick={handleClickIncrement}>Counter: {counter}</button>;
};

¿Qué hace la llamada a useState?

  • Declara una “variable de estado”.
  • useState es una nueva forma de usar exactamente las mismas funciones que this.state nos da en una clase.
  • Normalmente, las variables “desaparecen” cuando se sale de la función, pero las variables de estado son conservadas por React.

¿Qué pasamos a useState como argumento?

  • El único argumento para el Hook useState() es el estado inicial.

¿Qué devuelve useState?

  • Devuelve una pareja de valores (array): el estado actual y una función que lo actualiza.

Resumen:

  • Declaramos una variable de estado llamada contador y le asignamos a 0.
  • React recordará su valor actual entre re-renderizados, y devolverá el valor más reciente a nuestra función.
  • Si se quiere actualizar el valor de contador actual, podemos llamar a setContador.
  • Cuando el usuario hace click, llamamos a setContador con un nuevo valor. React actualizará entonces el componente Contador pasándole el nuevo valor de contador.
  • Nota los corchetes son intaxis de Javascript, se llama “desestructuración de arrays”.

Práctica

jsx
import { useState } from "react";

const App = () => {
  const [count, setCount] = useState(0);

  const handleClickDecrement = () => {
    setCount(count - 1);
  };

  const handleClickIncrement = () => {
    setCount(count + 1);
  };

  return (
    <div className="container mt-5 text-center">
      <div className="row justify-content-center">
        <div className="col-5">
          <h1>Counter {count}</h1>
          <div className="d-grid gap-2">
            <button
              className="btn btn-outline-danger"
              onClick={handleClickDecrement}
              disabled={count === 0 && true}
            >
              Decrement
            </button>
            <button
              className="btn btn-outline-primary"
              onClick={handleClickIncrement}
            >
              Increment
            </button>
            <button
              className="btn btn-outline-dark"
              onClick={() => setCount(0)}
            >
              Reset
            </button>
          </div>
        </div>
      </div>
    </div>
  );
};

export default App;

Opción #01 ActionButton:

jsx
const ActionButton = ({ count = 0, color = "secondary", action }) => {
  return (
    <button
      className={`btn btn-outline-${color}`}
      onClick={action}
    >
      Decrement {count}
    </button>
  );
};

export default ActionButton;
jsx
<ActionButton
  count={count}
  color="danger"
  action={handleClickDecrement}
/>

Opción #02 ActionButton:

jsx
const ActionButton = ({ count = 0, ...props }) => {
  return <button {...props}>Decrement {count}</button>;
};

export default ActionButton;
jsx
<ActionButton
  count={count}
  className="btn btn-outline-danger"
  onClick={handleClickDecrement}
  disabled={count === 0 && true}
/>

React.StrictMode

  • Quizás notaste el modo estricto en React, esto nos ayuda a detectar posibles errores en modo desarrollo.
    • Verificar que los componentes internos estén siguiendo algunas de las prácticas recomendadas y le avise si no está en la consola.
    • Verificar que los métodos en desuso no se estén usando y, si se usan, el modo estricto le avisará en la consola.
    • Ayudarle a prevenir algunos efectos secundarios mediante la identificación de riesgos potenciales.
  • StrictMode React 18

WARNING

  • StrictMode renderizará los componentes dos veces solo en el modo de desarrollo, no en el de producción.
  • StrictMode renderiza los componentes dos veces para detectar cualquier problema con su código y advertirle sobre ellos.

¿Qué está pasando acá?

  • Estamos utilizando destructuring, rest operator y spread operator. tutorial aquí
  • const ActionButton = ({ count = 0, ...props }) En esta línea estamos aplicando destructuring: inicializando count como una variable y el "resto" (rest operator) se va a una variable props.
  • <button {...props}> aquí aplicamos la sintaxis extendida (Spread operator) expande iterables en elementos individuales.

Siguiente Clase

  • ¿Cómo utilizar state con objetos o arrays?