DEV Community

Cover image for How I Built A Github RepoSearch App Using Reactjs
Ifeoluwa Favour
Ifeoluwa Favour

Posted on

How I Built A Github RepoSearch App Using Reactjs

Let's get started.

About the App

RepoSearch App is simply a web App that Fetches Users' GitHub details and repository details. This is a project for my AltSchool Second Semester examination, and this is me sharing my process. .

I built the App using React, which is a JavaScript library for building user interfaces. The React App displays list of user's Repositories on GitHub, which routes to the details of each repository.

The Task

_

Implement an API fetch of your GitHub portfolio, show a page with a list of all your repositories on GitHub(the page should implement pagination for the repo list), and create another page showing data for a single repo clicked from the list of repos using nested routes while using all the necessary tools in react. Implement the proper SEO, Error Boundary (show a page to test the error boundary) and 404 pages. Good UI and Designs are important._

The Page was built using;

  • Semantic HTML5

  • CSS

  • ReactJs

The Process

  • Setting up React

To work with React for any project, the first thing to do is to create react application boilerplate using create-react-app

npx create-react-app my-app

Enter fullscreen mode Exit fullscreen mode

Installation of Some Dependencies Used

Image description

Before writing any line of codes in my App.js, i make sure to install Error Boundary to wrap all my codes in for easy readability of my code errors.

<ErrorBoundary FallbackComponent={ErrorFallback}>
       <App />

      </ErrorBoundary>
Enter fullscreen mode Exit fullscreen mode

Then on to the next...

  • Creating of Components

This gives a start to my project. The next thing i did was create a folder called "components" and another one called "pages" in the src folder.
Component is the base class for the React components defined as JavaScript classes. Then under Components i organized my work into different folders, for easy access, readability and reusability.
Also under my pages i organized the pages i'll be working with. See below ;

Image description

  • Fetching API

Then i implemented an API fetch for my GitHub repos search in my SearchBar.js.

 const getRepos = async (val) => {
    // condition that made sure that the fetch will only happen if the searchInput field is not empty
    if (searchInput) {
      const repos = await fetch(
        `https://api.github.com/users/${searchInput}/repos?per_page=8&page=${val}`
      );
      const data = await repos.json();
      setRepos(data);
    }
    return;
  };
Enter fullscreen mode Exit fullscreen mode

I also imported the necessary ReactHook i needed.

import React from "react";
import { useState } from "react";

Enter fullscreen mode Exit fullscreen mode

Then I created state variables inside my SearchBar.js to store the responses from the API fetch. The state will update as soon as the server sends the response.

const SearchBar = () => {
  const [searchInput, setSearchInput] = useState("");
  // I moved the repos and setRepos here from Result.js file
  const [repos, setRepos] = useState([]);

  const handleChange = (e) => {
    setSearchInput(e.target.value);
  };
Enter fullscreen mode Exit fullscreen mode

I created an async / await function called getRepos that made the API fetch request to the GitHub API.

 const getRepos = async (val) => {
    // condition that made sure that the fetch will only happen if the searchInput field is not empty
    if (searchInput) {
      const repos = await fetch(
        `https://api.github.com/users/${searchInput}/repos?per_page=8&page=${val}`
      );
      const data = await repos.json();
      setRepos(data);
    }
Enter fullscreen mode Exit fullscreen mode

Then i went ahead to render it

return (
    <>
      <p className="paragraph">Enter your github username below:</p>
      <div className="search-bar" style={{ padding: "50px" }}>
        <input
          type="text"
          placeholder="search"
          value={searchInput}
          onChange={handleChange}
        />
        {/* Call your getRepo function here instead of using useEffect */}
        <button className="search-button" onClick={() => getRepos(1)}>
          Search
        </button>
      </div>
      <Results
        className="repos-list"
        name={searchInput}
        repos={repos}
        getRepos={getRepos}
      />
    </>
Enter fullscreen mode Exit fullscreen mode

In Result.js file, i created a function called Results that getRepos once a particular GitHub username is being searched for in this format;

function Results({ repos, name, getRepos }) {
  return (
    <div className="repos">
      <h1 className="repo-header">Repositories</h1>
      <ul className="repo-container">
        {/* here, i added repos to the condition. so the map will only happen if all condition are true */}
        {repos &&
          repos[0] &&
          repos.map((repo, i) => (
            <a
              href={`https://github.com/${name}/${repo.name}`}
              key={i}
              target="_blank"
              rel="noreferrer"
            >
Enter fullscreen mode Exit fullscreen mode

and then rendered it also.

Halfway there...

  • Page Routing I then went ahead to route my pages using ReactRouter and i aslo created a 404 page for extra functionality.
<Routes>
          <Route path="/" element={<Home />} />
          <Route path="/RepositorySearch" element={<RepositorySearch />} />

          <Route path="*" element={<NotFound />} />
        </Routes>
Enter fullscreen mode Exit fullscreen mode

Styled up my page using CSS

  • Setting Up Pagination.

Pagination is a process that is used to divide large data into smaller discrete pages. Where a user can use links such as "next", "previous", and page numbers to navigate between pages, it enables a dynamic display of one page of results at a time.

Firstly, I started by creating the variable postPerPage, which specified the number of items that will be displayed on each page.
Then I created a state variable called pageNumbers which i set to totalPosts / postPerPage

const Pagination = ({ postsPerPage, totalPosts }) => {
  const pageNumbers = [];

  for (let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++) {
    pageNumbers.push(i);
  }
  return (
    <nav>
      <ul>
        {pageNumbers.map((number) => (
          <li key={number}>
            <a href="!#">{number}</a>
          </li>
        ))}
      </ul>
    </nav>
  );
};

Enter fullscreen mode Exit fullscreen mode

The state property pageNumbers determines the page that will be displayed. As it changes the displayed page changes too.

Next, I needed buttons...

So i created a Next and Previous buttons in my Resuslt.js file to paginate through the lists of Repos being displayed

<div className="buttons">
        <button onClick={() => getRepos(1)} className="previous">
          Previous
        </button>
        <button onClick={() => getRepos(2)} className="next">
          Next
        </button>
      </div>
Enter fullscreen mode Exit fullscreen mode

Then i styled it all using CSS.

CONCLUSION

This article is to just point out the process in which every implementation were made. Once agin, i was able to create my RepoSearch App with the help of React-Router, React-Error-Boundary, and GitHub API(for the API fetch) and all my styles were written in CSS(Cascading style sheet).

Here is the link to the source code https://github.com/iiphe/SearchRepos

And a link to the live code
https://search-reposapp.vercel.app/repositorySearch

Thank you for Reading

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more