react componentes - UDFJDC-ProgramacionAvanzada/Recursos GitHub Wiki

Crear una aplicación nueva en React

Para crear una aplicación nueva en React desde una terminal ejecute el comando npx create-react-app myapp, donde myapp corresponde al nombre de la aplicación. Esto creará una nueva carpeta denominada myapp.

Para ejecutar la aplicación creada ingrese a la carpeta, abra el proyecto en VSCode o en el editor de su preferencia, y desde una terminal ejecute el comando npm start.

Esto iniciará un servidor web que escucha peticiones en el puerto 3000 y abrirá una nueva ventana del navegador en la que se desplegará un contenido similar al que aparece en la siguiente imagen:

El archivo principal de la aplicación es src/index.js

import React from 'react';

import ReactDOM from 'react-dom/client';

import './index.css';

import App from './App';

import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(

 <React.StrictMode>

   <App />

 </React.StrictMode>

);

// If you want to start measuring performance in your app, pass a function

// to log results (for example: reportWebVitals(console.log))

// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals

reportWebVitals();

En este archivo podemos ver que se importan las librerías React y ReactDOM; el estilo principal de la página (./index.css); el componente principal App, y la librería reportWebVitals que es usada por React para medir el desempeño de la aplicación. 

Luego, a la constante root se le asigna el punto inicial donde se renderizará el componente principal de la aplicación. En este caso ese punto inicial es un elemento de la página que tiene como identificador (id) el texto root. Ese id puede ser localizado en el archivo /public/index.html en la parte correspondiente al cuerpo (body) de la página:

<body>

   <noscript>You need to enable JavaScript to run this app.</noscript>

   <div id="root"></div>

   <!--

     This HTML file is a template.

     If you open it directly in the browser, you will see an empty page.

     You can add webfonts, meta tags, or analytics to this file.

     The build step will place the bundled scripts into the <body> tag.

     To begin the development, run `npm start` or `yarn start`.

     To create a production bundle, use `npm run build` or `yarn build`.

   -->

 </body>

Crear un componente en una constante

Ahora vamos a modificar el componente principal usando para esto una constante. Para esto crearemos la constante component a la que le asignamos el valor <h1>Hola mundo</h1>. Luego renderizamos este componente. 

import React from "react";

import ReactDOM from "react-dom/client";

import "./index.css";

const root = ReactDOM.createRoot(document.getElementById("root"));

const component = <h1>Hola mundo</h1>;

root.render(component);

Guarde los cambios y vuelva al navegador donde podrá observar que el contenido de la página ha cambiado por un título de primer nivel con el texto Hola mundo. 

Note que en este caso el contenido de la constante component no es un string pero tampoco es HTML. Esta sintaxis se denomina JSX y es la que usa React para la implementación de los componentes. En este documento puede encontrar información adicional sobre JSX. 

Crear un componente en una función

La forma más habitual de crear componentes en React es mediante el uso de funciones (lo que también se conoce como componentes funcionales). Para ver un ejemplo revise el contenido del archivo /src/App.js:

Acá podemos ver que tenemos una función denominada App. Note que en este caso la convención de nombramiento para componentes funcionales, inicia con mayúscula (a diferencia de las funciones tradicionales que inician en minúscula).

Esta función retorna una expresión JSX. El componente es entonces un contenedor con la clase App. El contenedor tiene un header, el cual a su vez contiene una imagen, un párrafo y un enlace a la página oficial de React.

Note varias particularidades. A diferencia de HTML, en JSX el atributo de una etiqueta para hacer referencia a una clase no es class sino className dado que class es una palabra reservada de JSX. 

La imagen tiene un atributo src que corresponde a la ruta donde está almacenada la imagen. En este caso el valor se obtiene usando una expresión en JSX. Una expresión en JSX corresponde a una expresión válida en JavaScript a la que se envuelve dentro de llaves. Por tanto {logo} hace referencia a la variable logo definida en la primera importación del archivo. 

import logo from './logo.svg';

import './App.css';

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>

 );

}

Para renderizar este componente vamos a modificar el archivo src/index.js así:

import React from "react";

import ReactDOM from "react-dom/client";

import "./index.css";

import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(<App />);

Lo que hemos hecho es importar el componente App desde el archivo ./App (no se requiere ingresar la extensión .js). Luego este componente se renderiza envolviéndolo dentro de una nueva etiqueta HTML <App/>.

Pasar información a los componentes

Los componentes pueden recibir información para usarla a conveniencia. Esto se hace mediante el uso del objeto props. Para ejemplificar esto creemos un nuevo componente denominado Post. Para esto cree un nuevo archivo src/Post.js con el siguiente contenido:

function Post(props) {

 return (

   <div>

     <h1>Post</h1>

     <h2>Author: {props.author}</h2>

     <h2>Content: {props.content}</h2>

     <h2>Likes: {props.likes}</h2>

   </div>

 );

}

export default Post;

Este componente recibe como parámetro el objeto props; luego se usan los elementos de ese objeto para mostrar información acerca del autor, contenido y número de  likes de un post. 

Para renderizar este componente modificamos el archivo src/index.js así:

import React from "react";

import ReactDOM from "react-dom/client";

import "./index.css";

import Post from "./Post";

const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(

 <Post author="John Doe" content="This is the post content" likes={20} />

);

En este caso, en el componente Post se están definiendo tres atributos denominados author, content y likes. A cada atributo se le asigna un valor. Estos valores son capturados por el componente en el objeto props.

La vista del componente en el navegador quedará así:

Composición de componentes

Una aplicación web puede crearse mediante el uso y reuso de varios componentes. Reutilicemos el componente anterior así:

import React from "react";

import ReactDOM from "react-dom/client";

import "./index.css";

import Post from "./Post";

const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(

 <div>

   <Post author="John Doe" content="This is the post content" likes={20} />

   <Post author="Anne Hill" content="I like React" likes={3} />

   <Post author="Laia Martins" content="I love JSX" likes={0} />

 </div>

);

Acá podemos ver que estamos usando el componente Post tres veces. Cada componente tiene atributos diferentes. Estos tres componentes serán renderizados individualmente en la página. 

Renderizado condicional

En el ejemplo anterior cuando un post no tiene likes aparece el texto “Likes: 0”. Un diseñador podría tomar la decisión de mostrar un “llamado a la acción” para que el usuario de un like si la publicación aún no tiene. Para esto se podría usar un renderizado condicional.

En este código se crea la constante renderLikes a la cual se asigna una función. Esta función verifica la cantidad de likes que hay en la publicación. Si el número es cero se retorna un mensaje que invita a al usuario dar un like; en caso contrario se retorna el número de likes de la publicación. En el componente se hace ahora el llamado a esa función que hará un renderizado condicional. 

function Post(props) {

 const renderLikes = () => {

   if (props.likes === 0) return "Give us a like";

   else return "Likes: " + props.likes;

 };

 return (

   <div>

     <h1>Post</h1>

     <h2>Author: {props.author}</h2>

     <h2>Content: {props.content}</h2>

     <h2>{renderLikes()}</h2>

   </div>

 );

}

export default Post;

Incluir Bootstrap en React

Para incluir Bootstrap en React existen varias alternativas. Para este tutorial usaremos la librería react-bootstrap la cual se instala con el comando npm install react-bootstrap bootstrap.

Luego, en el archivo src/index.js incluimos la siguiente línea:

import 'bootstrap/dist/css/bootstrap.min.css';

Ahora vamos a ajustar el contenido de los posts usando tarjetas (cards) y el layout usando filas (row) y columnas (col). 

Modificamos el archivo src/index.js así:

import Container from "react-bootstrap/Container";

import Row from "react-bootstrap/Row";

import React from "react";

import ReactDOM from "react-dom/client";

import "./index.css";

import "bootstrap/dist/css/bootstrap.min.css";

import Post from "./Post";

const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(

 <Container className="mt-3">

   <Row>

     <Post author="John Doe" content="This is the post content" likes={20} />

     <Post author="Anne Hill" content="I like React" likes={3} />

     <Post author="Laia Martins" content="I love JSX" likes={0} />

   </Row>

 </Container>

);

Note que estamos incluyendo un contenedor y una fila para desplegar los elementos.

Ahora modificamos el archivo src/Post.js así:

import Button from "react-bootstrap/Button";

import Card from "react-bootstrap/Card";

import Col from "react-bootstrap/Col";

function Post(props) {

 const renderLikes = () => {

   if (props.likes === 0) return "Give us a like";

   else return "Likes" + props.likes;

 };

 return (

   <Col>

     <Card style={{ width: "18rem" }}>

       <Card.Body className="mb-3">

         <Card.Title>{props.author}</Card.Title>

         <Card.Text>{props.content}</Card.Text>

         <Card.Text>{renderLikes()}</Card.Text>

         <Button variant="primary">Like</Button>

       </Card.Body>

     </Card>

   </Col>

 );

}

export default Post;

En este archivo cada post es una tarjeta que se ubica en una columna.

Reaccionando a eventos

Ahora queremos que cuando el usuario haga clic en el botón “Like” el número de likes de cada post se incremente en uno. Para esto necesitamos que el componente reaccione al evento clic del botón. 

Iniciaremos creando la constante handleLikes a la que le asignamos una función. Esta función inicialmente mostrará un mensaje por consola indicando que el botón ha sido presionado. 

En el evento onClick del botón se le asigna la constante handleLikes

const handleLikes = () => {

   console.log("Button clicked...");

 };

 return (

   <Col>

     <Card style={{ width: "18rem" }}>

       <Card.Body className="mb-3">

         <Card.Title>{props.author}</Card.Title>

         <Card.Text>{props.content}</Card.Text>

         <Card.Text>{renderLikes()}</Card.Text>

         <Button variant="primary" onClick={handleLikes}>

           Like

         </Button>

       </Card.Body>

     </Card>

   </Col>

 );

Ahora cuando se hace clic en cada botón se podrá ver el mensaje en la consola del navegador:

El concepto de estado

Ahora el objetivo es cambiar el valor de la propiedad likes. Para hacer esto necesitamos introducir el concepto de estado. Esto lo veremos en un siguiente tutorial.

Reto

Crear una aplicación en React que represente una lista de tareas. Una tarea tiene un nombre, una descripción y un estado (creada, en progreso, completada). La aplicación deberá mostrar 10 tareas, cada una con un nombre diferente. Utilize un componente denominado Task para definir una tarea y un componente denominado TaskList para definir la lista de tareas.

⚠️ **GitHub.com Fallback** ⚠️