Guía 15: React - Hooks (useEffect)#
Actividades previas#
Open-Meteo#
Acceda al sitio Open-Meteo API.
Configure el API de Open-Meteo:
En la sección Location and Time, seleccione la zona de _America/Chicago (GMT-5)_.
Marque los indicadores: temperatura (Temperature (2 m)), humedad relativa (Relative Humidity (2 m)), temperatura aparente (Apparent Temperature) y velocidad del viento (Wind Speed (10 m)), en la sección Current Weather .
En Settings, escoja la configuración de las unidades de medida de la API, en este caso: temperatura (Celsius °C), velocidad del viento (km/h) y unidades de precipitación (Millimeter).
Compruebe la estructura del JSON en su navegador.
Ambiente de desarrollo#
Acceda a su proyecto dashboard en Codespaces o en su máquina local.
Cree y utilice la(s) rama(s) de desarrollo.
Instale los paquetes y levante el servidor, con:
npm install npm run dev
Actividades en clases#
Tipos de datos e Interfaces#
Acceda al sitio Transform Tools / JSON to TypeScript.
Utilice el JSON de salida de la API de Open-Meteo para generar las interfaces de TypeScript.
Dentro de su proyecto dashboard:
Cree el archivo src/types/DashboardTypes.tsx
Coloque el código de las interfaces generadas en el paso anterior y modifique el nombre de la interfaz Root por OpenMeteoResponse.
Utilice su cliente de IAG para justificar el uso de las interfaces y el tipo de datos que representan.
IndicatorUI#
Revise la documentación del componente Card.
Cree el componente funcional IndicatorUI en el archivo src/components/IndicatorUI.tsx, con el siguiente código:
import Card from '@mui/material/Card'; import CardContent from '@mui/material/CardContent'; import Typography from '@mui/material/Typography'; interface IndicatorUIProps { title?: string; description?: string; } export default function IndicatorUI(props: IndicatorUIProps) { return ( <Card> <CardContent sx={{ height: '100%' }}> <Typography variant="h5" component="div"> {props.description} </Typography> <Typography variant="body2" component="p" color="text.secondary"> {props.title} </Typography> </CardContent> </Card> ) }
Modifique el archivo src/App.tsx, con:
Importe el componente IndicatorUI desde el archivo ./components/IndicatorUI.
En la sección en la seccion Indicadores:
Convierta el componente Grid un _contenedor_.
Agregue cuatro componentes IndicatorUI con los indicadores Temperatura (2m), Temperatura aparente, Velocidad del viento y Humedad relativa.
... import IndicatorUI from './components/IndicatorUI'; ... function App() { ... return ( <Grid ... > {/* Indicadores */} <Grid container size={{ xs: 12, md: 9 }} > <Grid size={{ xs: 12, md: 3 }}> <IndicatorUI title='Temperatura (2m)' description='XX°C' /> </Grid> <Grid size={{ xs: 12, md: 3 }}> {/* IndicatorUI con la Temperatura aparente en °C' */} </Grid> <Grid size={{ xs: 12, md: 3 }}> {/* IndicatorUI con la Velocidad del viento en km/h' */} </Grid> <Grid size={{ xs: 12, md: 3 }}> {/* IndicatorUI con la Humedad relativa en %' */} </Grid> </Grid> </Grid> ) }
Complete los componentes IndicatorUI con los valores de los indicadores y sus unidades.
Compruebe la vista previa del resultado en el navegador.
React - Hook: useEffect#
Nota
Considere la explicación del uso del hook useEffect.
useFetchData#
Cree el componente funcional useFetchData en el archivo src/hooks/useFetchData.tsx.
Cree el componente useFetchData, con:
Importe los hooks useState y useEffect de React.
Importe la interfaz como tipos de datos (type) OpenMeteoResponse del archivo ../types/DashboardTypes.tsx.
Declare que el componente useFetchData retorna un objeto del tipo OpenMeteoResponse.
Ver la solución
import { useEffect, useState } from 'react'; import { type OpenMeteoResponse } from '../types/DashboardTypes'; export default function useFetchData() : OpenMeteoResponse { }
Dentro de useFetchData:
Declare la constante de estado data y la función de actualización setData del tipo OpenMeteoResponse (o null). El valor predeterminado es de tipo null.
Defina la constante URL con el endpoint de los datos de Open-Meteo.
Agregue el hook useEffect para que reaccione únicamente después del primer renderizado del DOM.
Retorne data al final del componente.
Ver la solución
export default function useFetchData() : OpenMeteoResponse { const URL = 'https://api.open-meteo.com/v1/forecast ... '; const [data, setData] = useState<OpenMeteoResponse>(); useEffect(() => { }, []); // El array vacío asegura que el efecto se ejecute solo una vez después del primer renderizado return data; }
Dentro del función flecha del useEffect, realice un requerimiento asíncrono con la URL del endpoint. Al completarse la petición, actualice el estado data con la respuesta en formato JSON.
Con un cliente de IAG, explique el uso del hook useEffect y la configuración del arreglo de dependencias.
App.tsx#
Importe y almacene su salida en una constante dataFetcherOutput en el archivo src/App.tsx.
... import useFetchData from './hooks/useFetchData'; ... function App() { ... const dataFetcherOutput = useFetchData(); ... return ( ... ) }
Modifique el archivo src/App.tsx, con:
En el componente IndicatorUI para el indicador Temperatura (2m)
Utilice dataFetcherOutput para validar el renderizado del indicador con el valor de temperature_2m y su unidad. Revise la estructura del JSON.
Ver la solución
... <Grid size={{ xs: 12, md: 3 }}> {dataFetcherOutput && (<IndicatorUI title='Temperatura (2m)' description={ `${dataFetcherOutput.current.temperature_2m} ${dataFetcherOutput.current_units.temperature_2m}` } />) } </Grid> ...
Renderice los demás indicadores con los datos correspondientes de dataFetcherOutput.
Compruebe el resultado de la petición asíncrona del navegador.
Versionamiento#
Versione local y remotamente la(s) rama(s) de desarrollo en el repositorio dashboard.
Genere la(s) solicitud(es) de cambios (pull request) para la rama principal y apruebe los cambios.
Despliegue#
Desde la línea de comandos, ejecute el comando de transpilación y despliegue del sitio web, con:
npm run deploy
De ser necesario, elimine, corrija o comente las secciones de código identificadas por el transpilador.
Vuelva a ejecutar el comando de transpilación y despliegue del sitio web.
Compruebe el resultado en el navegador, con la URL: https://<username>.github.io/dashboard
Conclusiones#
Actividades autónomas#
Recursos extras#
En redes:
⚛️ useEffect cheatsheet ↓
— George Moller (@_georgemoller) October 17, 2023
❌ Thinking of useEffect as a lifecycle method.
✅ Thinking of useEffect as a mechanism to sync data (state/props) with systems that aren’t controlled by React. pic.twitter.com/v8BK5CLsSn