React Dojo

Buscar

Busca conceptos, ejercicios y quizzes

utility

useGitHubStars

Obtiene las estrellas de un repositorio público de GitHub. Incluye caché en memoria con TTL de 1 hora para respetar el rate limit de la API y cancelación automática si el repo cambia.


useGitHubStars.ts
import { useState, useEffect } from "react"

interface GitHubStarsState {
  stars: number | null
  loading: boolean
  error: string | null
}

const cache = new Map<string, { value: number; ts: number }>()
const TTL_MS = 60 * 60 * 1000 // 1 hora

export function useGitHubStars(repo: string): GitHubStarsState {
  const [state, setState] = useState<GitHubStarsState>({
    stars: null,
    loading: true,
    error: null,
  })

  useEffect(() => {
    const cached = cache.get(repo)
    if (cached && Date.now() - cached.ts < TTL_MS) {
      setState({ stars: cached.value, loading: false, error: null })
      return
    }

    let cancelled = false
    setState({ stars: null, loading: true, error: null })

    fetch(`https://api.github.com/repos/${repo}`)
      .then((res) => {
        if (!res.ok) throw new Error(`HTTP ${res.status}`)
        return res.json()
      })
      .then((data) => {
        if (!cancelled && typeof data.stargazers_count === "number") {
          cache.set(repo, { value: data.stargazers_count, ts: Date.now() })
          setState({ stars: data.stargazers_count, loading: false, error: null })
        }
      })
      .catch((err) => {
        if (!cancelled) setState({ stars: null, loading: false, error: err.message })
      })

    return () => { cancelled = true }
  }, [repo])

  return state
}
¿Fue útil?
Inicia sesión para dar feedback