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