Maison >interface Web >js tutoriel >Comment ajouter des statistiques de contribution GitHub à votre application React

Comment ajouter des statistiques de contribution GitHub à votre application React

Barbara Streisand
Barbara Streisandoriginal
2025-01-15 09:10:47948parcourir

How to Add GitHub Contribution Stats to Your React App

Vous souhaitez présenter votre activité GitHub dans votre portfolio React ? Dans ce didacticiel, je vais vous montrer comment créer un composant React qui affiche le total de vos contributions GitHub à l'aide de l'API GraphQL de GitHub, avec une mise en cache efficace. Créons quelque chose de cool ! ?

Ce que nous allons construire

Nous allons créer un composant React qui :

  • Récupère vos contributions GitHub de 2020 à aujourd'hui
  • Comprend les contributions publiques et privées
  • Implémente la mise en cache côté client pour optimiser les performances
  • Affiche un état de chargement lors de la récupération
  • Gère les erreurs avec élégance

Conditions préalables

Avant de commencer, vous aurez besoin de :

  1. Un jeton d'accès personnel GitHub (avec portée read:user)
  2. Un projet React configuré (à l'aide de Create React App, Next.js ou de votre configuration préférée)
  3. Connaissance de base des hooks React et des opérations asynchrones

Étape 1 : configuration du jeton GitHub

Tout d'abord, créez un fichier .env à la racine de votre projet et ajoutez votre jeton GitHub :

NEXT_PUBLIC_GITHUB_TOKEN=your_github_token_here

Étape 2 : Création de l'utilitaire de récupération de données

Créez un nouveau fichier appelé githubApi.js :

export async function fetchGithubCommits(username) {
  const GITHUB_TOKEN = process.env.NEXT_PUBLIC_GITHUB_TOKEN;
  const CACHE_KEY = `github-commits-${username}`;
  const CACHE_TTL = 3600; // 1 hour in seconds

  if (!GITHUB_TOKEN) {
    console.error("No GitHub token found!");
    throw new Error("GitHub token is required");
  }

  const cachedData = getCachedData(CACHE_KEY);
  if (cachedData) {
    return cachedData.value;
  }

  try {
    const currentYear = new Date().getFullYear();
    const startYear = 2020;
    let totalCommits = 0;

    for (let year = startYear; year <= currentYear; year++) {
      const query = `
        query($username: String!, $from: DateTime!, $to: DateTime!) {
          user(login: $username) {
            contributionsCollection(from: $from, to: $to) {
              totalCommitContributions
              restrictedContributionsCount
            }
          }
        }
      `;

      const response = await fetch("https://api.github.com/graphql", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${GITHUB_TOKEN}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          query,
          variables: {
            username,
            from: `${year}-01-01T00:00:00Z`,
            to: `${year}-12-31T23:59:59Z`,
          },
        }),
      });

      const data = await response.json();
      if (data.errors) {
        throw new Error(data.errors[0].message);
      }

      const yearCommits =
        (data.data?.user?.contributionsCollection?.totalCommitContributions || 0) +
        (data.data?.user?.contributionsCollection?.restrictedContributionsCount || 0);

      totalCommits += yearCommits;
    }

    setCachedData(CACHE_KEY, totalCommits, CACHE_TTL);
    return totalCommits;
  } catch (error) {
    console.error("Error fetching GitHub commits:", error);
    throw error;
  }
}

function setCachedData(key, value, ttl) {
  const item = {
    value,
    timestamp: Date.now(),
    ttl: ttl * 1000,
  };
  localStorage.setItem(key, JSON.stringify(item));
}

function getCachedData(key) {
  try {
    const item = localStorage.getItem(key);
    if (!item) return null;

    const parsedItem = JSON.parse(item);
    const now = Date.now();

    if (now - parsedItem.timestamp > parsedItem.ttl) {
      localStorage.removeItem(key);
      return null;
    }

    return parsedItem;
  } catch {
    return null;
  }
}

export function invalidateCommitsCache(username) {
  localStorage.removeItem(`github-commits-${username}`);
}

Étape 3 : Création du composant React

Créez un nouveau fichier appelé GitHubStats.js :

import React, { useState, useEffect } from 'react';
import { fetchGithubCommits } from './githubApi';

const GitHubStats = ({ username }) => {
  const [commits, setCommits] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchStats = async () => {
      try {
        setLoading(true);
        setError(null);
        const totalCommits = await fetchGithubCommits(username);
        setCommits(totalCommits);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchStats();
  }, [username]);

  if (loading) {
    return <div>Loading GitHub stats...</div>;
  }

  if (error) {
    return <div>Error: {error}</div>;
  }

  return (
    <div className="github-stats">
      <h2>GitHub Contributions</h2>
      <p>Total commits since 2020: {commits.toLocaleString()}</p>
    </div>
  );
};

export default GitHubStats;

Étape 4 : Ajout de styles

Ajoutons un style de base. Créez GitHubStats.css :

.github-stats {
  padding: 20px;
  border-radius: 8px;
  background-color: #f6f8fa;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  margin: 20px 0;
}

.github-stats h2 {
  margin: 0 0 15px 0;
  color: #24292e;
}

.github-stats p {
  font-size: 1.2em;
  color: #586069;
}

Étape 5 : Utilisation du composant

Vous pouvez désormais utiliser le composant dans votre application :

import GitHubStats from './GitHubStats';

function App() {
  return (
    <div className="App">
      <h1>My Developer Portfolio</h1>
      <GitHubStats username="your-github-username" />
    </div>
  );
}

Améliorer les choses : fonctionnalités avancées

1. Ajout d'un bouton d'actualisation

Mettez à jour GitHubStats.js pour inclure une option d'actualisation manuelle :

import React, { useState, useEffect } from 'react';
import { fetchGithubCommits, invalidateCommitsCache } from './githubApi';

const GitHubStats = ({ username }) => {
  // ... previous state declarations ...

  const handleRefresh = async () => {
    invalidateCommitsCache(username);
    await fetchStats();
  };

  return (
    <div className="github-stats">
      <h2>GitHub Contributions</h2>
      <p>Total commits since 2020: {commits.toLocaleString()}</p>
      <button onClick={handleRefresh} disabled={loading}>
        {loading ? 'Refreshing...' : 'Refresh Stats'}
      </button>
    </div>
  );
};

2. Ajout d'une répartition année par année

Nous pouvons modifier le composant pour afficher les cotisations par an :

NEXT_PUBLIC_GITHUB_TOKEN=your_github_token_here

Conseils de performances

  1. Stratégie de mise en cache : la mise en œuvre actuelle met les données en cache pendant une heure. Ajustez le CACHE_TTL en fonction de vos besoins.
  2. Limites d'erreur  : pensez à envelopper le composant dans une limite d'erreur pour gérer les erreurs inattendues avec élégance.
  3. États de chargement : ajoutez un chargeur squelette au lieu d'un simple texte "Chargement..." pour une meilleure UX.

Problèmes courants et solutions

  1. Problèmes CORS : assurez-vous que vous utilisez le bon point de terminaison et les en-têtes de l'API GitHub.
  2. Autorisations du jeton : assurez-vous que votre jeton GitHub dispose des autorisations requises.
  3. Limitation du débit : gérez les limites de débit de l'API de GitHub en vérifiant la limite de débit restante dans les en-têtes de réponse.

Vous disposez désormais d'un composant de statistiques GitHub entièrement fonctionnel dans votre application React ! Cette implémentation fournit une base solide sur laquelle vous pouvez vous appuyer. Quelques idées d'amélioration :

  • Ajoutez plus de statistiques GitHub (comme les étoiles, les PR, les problèmes)
  • Créer des représentations visuelles à l'aide de graphiques
  • Ajouter des animations pour le chargement et les mises à jour
  • Implémenter une gestion des erreurs plus détaillée

N'oubliez pas de garder votre jeton GitHub en sécurité et de ne jamais le valider dans votre référentiel. Bon codage ! ?

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn