首页 > web前端 > js教程 > 如何将 GitHub 贡献统计添加到您的 React 应用程序

如何将 GitHub 贡献统计添加到您的 React 应用程序

Barbara Streisand
发布: 2025-01-15 09:10:47
原创
943 人浏览过

How to Add GitHub Contribution Stats to Your React App

想要在 React 作品集中展示您的 GitHub 活动?在本教程中,我将向您展示如何创建一个 React 组件,该组件使用 GitHub 的 GraphQL API 显示您的 GitHub 贡献总量,并配有高效的缓存。让我们构建一些很酷的东西! ?

我们将构建什么

我们将创建一个 React 组件:

  • 获取您从 2020 年至今的 GitHub 贡献
  • 包括公共和私人捐款
  • 实现客户端缓存以优化性能
  • 获取时显示加载状态
  • 优雅地处理错误

先决条件

在我们开始之前,您需要:

  1. GitHub 个人访问令牌(具有 read:user 范围)
  2. React 项目设置(使用 Create React App、Next.js 或您的首选设置)
  3. React hooks 和异步操作的基础知识

第 1 步:设置 GitHub 令牌

首先,在项目根目录中创建一个 .env 文件并添加您的 GitHub 令牌:

NEXT_PUBLIC_GITHUB_TOKEN=your_github_token_here
登录后复制
登录后复制

第 2 步:创建数据获取实用程序

创建一个名为 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}`);
}
登录后复制

第 3 步:创建 React 组件

创建一个名为 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;
登录后复制

第四步:添加样式

让我们添加一些基本样式。创建 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;
}
登录后复制

第 5 步:使用组件

现在您可以在应用程序中使用该组件:

import GitHubStats from './GitHubStats';

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

让它变得更好:高级功能

1.添加刷新按钮

更新 GitHubStats.js 以包含手动刷新选项:

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. 添加逐年细分

我们可以修改组件以显示每年的贡献:

NEXT_PUBLIC_GITHUB_TOKEN=your_github_token_here
登录后复制
登录后复制

性能技巧

  1. 缓存策略:当前实现缓存数据一小时。根据您的需要调整 CACHE_TTL。
  2. 错误边界:考虑将组件包装在错误边界中以优雅地处理意外错误。
  3. 加载状态:添加骨架加载器而不是简单的“正在加载...”文本以获得更好的用户体验。

常见问题及解决方案

  1. CORS 问题:确保您使用正确的 GitHub API 端点和标头。
  2. 令牌权限:确保您的 GitHub 令牌具有所需的权限。
  3. 速率限制:通过检查响应标头中的剩余速率限制来处理 GitHub 的 API 速率限制。

现在,您的 React 应用程序中已经有了一个功能齐全的 GitHub stats 组件!此实施为您的构建提供了坚实的基础。一些增强的想法:

  • 添加更多 GitHub 统计信息(例如星星、PR、问题)
  • 使用图表创建视觉表示
  • 添加加载和更新动画
  • 实施更详细的错误处理

请记住确保您的 GitHub 令牌安全,切勿将其提交到您的存储库。快乐编码! ?

以上是如何将 GitHub 贡献统计添加到您的 React 应用程序的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板