Introducció
useEffect
es un hook de React que te permite sincronizar un componente con un sistema externo.
Obtenir dades
Fetch
A React, per utilitzar la funció fetch
ho has de fer amb el "hook" useEffect
.
En aquest exemple obtenim una llista de posts amb la funció fetch
:
import { useEffect, useState } from "react"
export default function App() {
const [posts, setPosts] = useState([])
useEffect(() => {
(async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=10')
const data = await response.json()
setPosts(data)
})()
}, [])
return (
<div className="container">
<ul className="list-group mt-5">
{posts.map(post => <li className="list-group-item">{post.title}</li>)}
</ul>
</div>
)
}
Activitat. Afegeix un missatge d'error:
import { useEffect, useState } from "react"
export default function App() {
const [currentTime, setCurrentTime] = useState(0)
const [log, setLog] = useState("")
useEffect(() => {
const fetchTime = async () => {
const response = await fetch('/api/time')
if (response.status != 200) {
setLog(response.statusText)
return
}
const data = await response.json()
setCurrentTime(data.time)
}
fetchTime()
}, [])
return (
<div className="container">
<p className="text-center m-5 p-5 fs-3">The current time is {currentTime}.</p>
<p className="text-center text-danger fs-4">{log}</p>
</div>
)
}
SWR
SWR és una biblioteca React Hooks per a l'obtenció de dades.
El nombre “SWR” es derivado de stale-while-revalidate, una estrategia de invalidación de caché HTTP popularizada por HTTP RFC 5861 (opens in a new tab).
SWR es una estrategia para devolver primero los datos en caché (obsoletos), luego envíe la solicitud de recuperación (revalidación), y finalmente entrege los datos actualizados.
Con SWR el componente obtendrá constante y automáticamente el último flujo de datos. Y la interfaz de usuario será siempre rápida y reactiva.
Instal.la swr
:
$ bun install swr
En este ejemplo, el hook useSWR acepta una key que es un cadena y una función fetcher. key es un indentificador único de los datos (normalmente la URL de la API) y pasará al fetcher. El fetcher puede ser cualquier función asíncrona que devuelve datos, puedes utilizar el fetch nativo o herramientas como Axios.
El hook devuelve 2 valores: data y error, basados en el estado de la solicitud.
import useSWR from 'swr'
export default function App() {
return <Countries />
}
function Countries() {
// created function to handle API request
const fetcher = (arg: any, ...args: any) => fetch(arg, ...args).then((res) => res.json());
const { data: countries, error, isValidating,
} = useSWR('https://restcountries.com/v2/all', fetcher)
// Handles error and loading state
if (error)
return <p className="m-5 text-center fs-3">Failed to load</p>
if (isValidating)
return <p className="m-5 text-center fs-3">Loading...</p>
return (
<div>
{countries.map((country: any, index: number) => (
<img key={index} src={country.flags.png} width={100} />
))}
</div>
)
}
Activitats
1.- Mostra la recepta que et mostra aquest enllaç: https://www.themealdb.com/api/json/v1/1/random.php:
import useSWR from 'swr'
export default function App() {
return (
<div className="container">
<Meal />
</div>
)
}
function Meal() {
// created function to handle API request
const fetcher = (arg: any, ...args: any) => fetch(arg, ...args).then((res) => res.json());
const {
data: data, error, isValidating,
} = useSWR("https://www.themealdb.com/api/json/v1/1/random.php", fetcher)
// Handles error and loading state
if (error)
return <p className="m-5 text-center fs-3">Failed to load</p>
if (isValidating)
return <p className="m-5 text-center fs-3">Loading...</p>
const meal = data.meals[0]
return (
<>
<h2 className='text-center'>{meal.strMeal}</h2>
<img src={meal.strMealThumb} />
<p className="border border-3">{meal.strInstructions}</p>
</>
)
}
2.- Mostra alguna informació d'aquest repositori: https://rickandmortyapi.com/documentation
Per exemple, el personatge https://rickandmortyapi.com/api/character/2
import useSWR from 'swr'
export default function App() {
return (
<div className="container">
<Character />
</div>
)
}
function Character() {
// created function to handle API request
const fetcher = (arg: any, ...args: any) => fetch(arg, ...args).then((res) => res.json());
const {
data: character, error, isValidating,
} = useSWR("https://rickandmortyapi.com/api/character/2", fetcher)
// Handles error and loading state
if (error)
return <p className="m-5 text-center fs-3">Failed to load</p>
if (isValidating)
return <p className="m-5 text-center fs-3">Loading...</p>
return (
<>
<h2>{character.name}</h2>
<p>{character.species}</p>
<img src={character.image} />
</>
)
}
TODO
- https://www.freecodecamp.org/news/how-to-fetch-api-data-in-react/
- https://dev.to/franklin030601/hacer-un-fetching-de-datos-y-crear-un-custom-hook-4bjh
- https://es.react.dev/reference/react/useEffect#fetching-data-with-effects
- https://overreacted.io/a-complete-guide-to-useeffect/
- https://medium.com/@bhanu.mt.1501/api-calls-in-react-js-342a09d5315f