How to Use the GitHub API to List and set up pagination for a single user Repositories with React.
As a software engineer, you probably use GitHub quite often, be it as part of your day job, while working on your solo projects, or when contributing to open source.
GitHub is one of the best ways to collaborate on software and discover new projects using Git, the popular Version Control System (VCS). It's safe to say that GitHub is a huge part of the Open Source Software movement that is continually pushing the bounds of technology as we know it by helping developers contribute to more projects and network with other developers.
In this article, you will learn how to use the GitHub API to fetch user information and list out their repositories while also setting up client-side pagination and routing with React.
Prerequisites
Web browser
DevTools
npm installed
Reactjs installed
Familiarity with React.JS and its extensions such as react-router, react-dom and react-helmet. However, if new to the world of React here is a quick view of how to get started.
Setting up React Application
Below is a simple guide to setting up a react application and also some dependencies used in this project.
npx create-react-app my-app
cd my-app
npm run dev
Note that the " my-app" can be any name of your choice.
Setting up a React Router
React Router is a standard library for routing in React. It enables the navigation among views of various components in a React Application, allows changing the browser URL, and keeps the UI in sync with the URL. It has a simple API with powerful features like lazy code loading, dynamic route matching, and location transition handling built right in. To install React Router, below is a guide to be executed in the project terminal.
npm install react-router-dom@6
Fetching data from GitHub API
Understanding how to consume a rest API is very essential.
As a quick refresher, a REST API is an API that maps a resource to an endpoint. Resource, in this case, means any piece of data necessary for an application to function. For instance, a list of users resource(s) could be mapped to a /user
endpoint. For this article, we will be consuming the Github API to get a user's detail and specifically my GitHub profile.
Using Fetch to make an API request in react
Fetch API is a web standard that is implemented in all major browsers to allow for making network requests in a standardized way.
To get my GitHub profile information, the API below would be used.
https://api.github.com/users/achele
Open the GithubPortfolio.jsx
file and import some React hooks:
import { useState, useEffect } from "react";
import { GoMarkGithub, GoStar, GoRepo, GoRepoForked, GoOrganization, GoLocation, GoMention } from "react-icons/go"
import{FaTwitter} from "react-icons/fa"
We need to store the response (or error, if any) from calling the API in React state. Initialize two state variables:
export default function GithubPortfolio() {
const [page, setPage] = useState()
const url = "https://api.github.com/users/achele"
const { loading, data } = useFetch(url)
console.log(data)
Furthermore, We need to query the REST API endpoint when The GithubPortfolio component is
mounted and for that, we’ll use the useEffect
hook: By using this Hook, you tell React that your component needs to perform a function after rendering. React will remember the function passed, and call it later after performing the DOM updates.
useEffect(()=>{
const fetchData=async()=>{
setLoading(true)
try {
const res =await fetch(url)
const doc = await res.json()
setLoading(false)
setData(doc)
} catch (error) {
setLoading(false)
handleError(error);
}
}
fetchData()
},[url])
return{loading,data}
}
To make my code reusable, a component was created to handle the useEffect. Here, two states were initialized
const [loading,setLoading]=useState(false)
const [data,setData]=useState([])
Also, another component was initialized to fetch a list of all my repositories
export default function Repositories() {
const [repos, setRepos] = useState([]);
const [page, setPage] = useState()
// const handleError = useErrorHandler();
const total = 6
const url = `https://api.github.com/users/achele/repos? page=${page}&per_page=5`
const { loading, data } = useFetch(url)
console.log(data)
return (
<HelmetProvider>
<Helmet>
<title>Achez Github Repositories</title>
<meta name="description" content="list of Achez Repositories" />
</Helmet>
<NavBar />
<main>
<div className="flex repos">
<GoRepo className="repo-icon"/>
<h4>Repositories</h4>
</div>
{loading && <p className="loading">loading</p>}
{data && data.map(details => <li key={details.id} className="repoList-card ">
<section className="flex star">
<div>
<div className="flex">
<h3>{details.full_name}</h3>
{details.private ? (<h4> Private</h4>) : (<h4> Public</h4>)}
</div>
<div className="repo-info">
{details.language ? <p>🟢{details.language}</p> : (<p>🟢null</p>)}
<p> Updated {" "}
{formatDistance(subDays(new Date(details.updated_at), 3), new Date(), { addSuffix: true })}
</p>
</div>
</div>
{details.stargazers_count > 0 && (
<div className="flex">
<GoStar/>
<p>Starred</p>
</div>
)}
{details.stargazers_count === 0 && (
<div className="flex">
<GoStar/>
<p>Star</p>
</div>
)}
</section>
<Link to="repo" state={{ details: details }}>See more...</Link>
<hr />
</li>
)}
Implement Pagination
Decide on the number of records to be displayed per page and the number of pages. I decided on a total number of 6 and a single page of 5. Also, I thought of keeping track of the page number, the user is on. The states were created.
export default function Repositories() {
const [repos, setRepos] = useState([]);
const [page, setPage] = useState()
const total = 6
const url = `https://api.github.com/users/achele/repos? page=${page}&per_page=5`
displaying output in the return statement, note that the codes must be wrapped in React fragments or a div.
<div className="btn-container">
<button disabled={page <= 1} onClick={() => setPage(prev => prev - 1)}>prev</button>
<p>{page}</p>
{Array.from({ length: total }, (value, index) => index + 1).map((doc) => <button onClick={() => setPage(doc)} key={doc}>{doc}</button>
)}
<button disabled={page >= 6} onClick={() => setPage(prev => prev + 1)}>next</button>
</div>
Implementing Nested Route
Nested Route is the ability of a react project to have multiple components rendered on the same page, As the word implies a nested route is a route that is nested inside another route, that is, a route in a route, the structure of the implemented nested route is as follows:
<Route path='repositories' element={<Repositories />}>
<Route path='repo' element={<Repo />} />
</Route>
From the above example, the nested Route has the name "Repo" and it is rendered inside the "Repositories" route.
Conclusion
GitHub is a significant part of the day-to-day working lives of many software engineers. GitHub provides one of the nicest RESTful APIs out there. It's easy to get started with, follows good standards, and is, generally speaking, well-documented.
In this post, I've walked you through the process of using the GitHub API to list a user's repositories such as having a design in mind, understanding the various features that will be implemented, getting react started on your editor and importing all necessary dependencies. furthermore, having a folder and file structure, and setting up pagination.
Thanks for reading...