Taller: React con hooks I

Un taller de React con hooks en tiempos de cuarentena.

Catrin Welz-Stein

archivado en: JavaScript / 24 marzo, 2020

Llevaba dos o tres años sin escribir nada por aquí, ya que he estado embarcado en otros proyectos, pero como están siendo días complicados por la pandemia del covid y el confinamiento, os propongo un taller de react con typescript y hooks que nos permita pensar en otras cosas y que espero encontréis de utilidad.

El taller consistirá en realizar una aplicación muy sencilla, pero que incorpore técnicas propias de una aplicación grande, como el enrutado o la carga lazy load. Aquí podéis ver el resultado final y aquí está el repo, aunque recomiendo ir siguiendo los pasos uno a uno.

Como podéis ver, la aplicación consiste en una vista donde cargaremos un listado de perros que hay en la api pública dog.ceo. Al seleccionar una especie o subespecie, habilitaremos un botón "Images", que al ser pulsado cargará las imágenes del animal seleccionado.

Para realizar la aplicación usaremos una versión de React superior a la 16.8, que se caracteriza por la incorporación de hooks y estar orientado a la programación funcional, redux, typescript, sass para los estilos y cypress para los tests e2e. Si me da tiempo, que tengo la suerte de seguir (tele)trabajando meteré también algo de PWA, jest y storybook.

Para seguirlo hay que tener ciertas nociones de react (no voy a explicar qué es un componente) y conviene que nos suenen los conceptos básicos de la programación funcional, que en esencia, en nuestro caso, se basa en montar todo el tinglado mediante funciones que van cambiando el estado general, el modelo de datos, mediante funciones predictivas, que siempre van a devolver el mismo resultado con los mismos parámetros de entrada. Si alguien quiere profundizar sobre la programación funcional en javaScript, le recomiendo una serie muy buena al respecto en El Abismo de null.

Bueno, pues vamos para allá...

Instalación

Lo primero es instalar todo el tinglado. Comenzamos con la base mediante el cli de react indicando que queremos usar de template typescript. Cambiar taller-react por el nombre que le queramos dar a la app.

npx create-react-app my-app --template typescript

Nos vamos al directorio que hemos creado y ahora lo que sigue se podría hacer todo del tirón, en una línea, pero lo iré desglosando para que quede más claro.

Instalamos sass.

 npm install node-sass --save-dev 

El router (react-router) y sus tipos.

npm install react-router-dom --save-dev 
npm install @types/react-router-dom --save-dev  

Los tipos de react y react-dom.

npm install --save-dev @types/react @types/react-dom

De momento con esto vale, más adelante instalaremos más cosas. Ahora vamos con la estructura del proyecto.

Scaffolding

Hay muchas maneras de estructurar un proyecto de react con typescript y hooks. Para grandes aplicaciones, a mí me suele venir bien algo así.

./src
  /assets
    /fonts
    /scss
  /components
    /grupo01
    /grupoN
  /core
    /config
    /rest
    /services
    /utils
  /routes
  /schemas
  /store
    store.ts
    /reducers
  /views
    /nombreVista
      nombreVista.ts
      /components
      /schemas

En assets meteremos todos los recursos de la aplicación que no sean código js, como las imágenes, las fuentes y las sass, que a su vez podemos estructurar siguiendo el patrón 7 x 1 siguiendo un patrón de diseño orientado a componentes con nomenclatura BEM.

En components podemos ir metiendo todos los componentes transversales de la aplicación, es decir, los que se van a usar en más de una vista, como la cabecera principal. Además, aquí conviene agruparlos a su vez por su naturaleza para que no nos quede luego un listado inmenso. Por ejemplo, podemos agrupar todos los que tienen que ver con formularios, con el layout (main-header, main-footer, main-sidebar...), con la interfaz de usuario (modal, notifications, spinner...), etcétera.

En views van las vistas, entendiendo por vista cada pantalla singular. Por ejemplo, esta sería la vista "artículo" de la wikipedia y esta otra la vista "ayuda". A su vez, dentro de cada directorio de cada vista podemos poner los componentes específicos de esa vista y los interfaces de typescript, que podemos agrupar en un directorio llamado schemas, models o whatever similar.

En core van todas las piezas que no son vistas ni componentes que se usan toda la aplicación, como los servicios, las utilidades generales, el sistema de gestión rest, etcétera.

Por último, en routes pondremos el enrutador; en schemas, los interfaces globales de la aplicación, los que afectan a más de una vista; y en store, el tinglado de redux.

El enrutado y las dos vistas

Vamos ahora con las dos vistas de la aplicación, una para cuando se acceda a una ruta que no exista (not found) y otra en la que mostraremos el listado de perros.

Preparamos la base para la vista not-found (observa que el archivo lleva por terminación .tsx, no .jsx).

// .src/views/not-found/view-not-found.tsx

import React from 'react';

const ViewNotFound: React.FC = () => {
  return (
    <section>
      Not found works
    </section>
  );
}

export default ViewNotFound;

Y otra para la vista del listado de perros.

// .src/views/dogs/view-dogs.tsx

import React from 'react';

const ViewDogs: React.FC = () => {
  return (
    <section>
      Dogs works
    </section>
  );
}

export default ViewDogs;

Como veis, no vamos a usar clases (que siguen pudiendo utilizarse si se necesita), sino una función arrow que hemos tipado como React.FC (React Function Component).

Ahora preparamos las rutas, que de momento irán sin lazy load.

// .src/routes/routes.tsx

import { Route, Switch } from 'react-router-dom';
import React from 'react';
import Dogs from '../views/dogs/view-dogs';
import NotFound from '../views/not-found/view-not-found';

export const Routes = () => (
    <Switch>
      <Route exact path="/" component={Dogs}/>
      <Route path="*" component={NotFound}/>
    </Switch>
);

Ahora vamos al archivo App.tsx, borramos todo el código de ejemplo que viene de fábrica y ponemos nuestro componente con las rutas.

// .src/App.tsx

import React from 'react';

import { BrowserRouter as Router } from 'react-router-dom';
import { Routes } from './routes/routes';

const App: React.FC = () => {
  return (
    <div>
      <Router>
        <Routes></Routes>
      </Router>
    </div>
  );
}

export default App;

Con todo esto listo, podemos levantar ya la aplicación ejecutando npm o yarn:

npm run start

Y nuestra app de momento debería lucir más o menos así.

Vale, pues ya con todo listo, empezamos con los hooks en la siguiente entrada.

|| Tags: , , ,

Este artículo aún no ha sido valorado.

¿Te ha parecido útil o interesante esta entrada?
dormido, valoración 1 nadapensativo, valoración 2 un poco sonrisa, valoración 3 a medias guiño, valoración 4 bastante aplauso, valoración 5 mucho

Tú opinión es muy importante, gracias por compartirla!

Aportar un comentario

*