<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Blessing Peters</title>
    <description>The latest articles on Forem by Blessing Peters (@blessingpeters).</description>
    <link>https://forem.com/blessingpeters</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F503664%2F3476de62-d666-4f55-84f3-6ab5ead8651a.jpeg</url>
      <title>Forem: Blessing Peters</title>
      <link>https://forem.com/blessingpeters</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/blessingpeters"/>
    <language>en</language>
    <item>
      <title>How I Integrated Emailjs Form Handling in my React App</title>
      <dc:creator>Blessing Peters</dc:creator>
      <pubDate>Thu, 26 Jan 2023 12:14:24 +0000</pubDate>
      <link>https://forem.com/blessingpeters/how-i-integrate-emailjs-form-handling-in-my-react-app-2fgj</link>
      <guid>https://forem.com/blessingpeters/how-i-integrate-emailjs-form-handling-in-my-react-app-2fgj</guid>
      <description>&lt;p&gt;As a front-end developer, at some point you may need to capture information from people who use your website through your contact forms. Platforms like emailJs, Netlify forms, forms-pree, etc. make this possible by allowing sending an email directly from your Javascript with no backend development&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Email JS&lt;/strong&gt; is a powerful tool for email form handling in React apps. It allows developers to quickly and easily add email forms to their React applications without having to write any code or manually manage any backend services. The platform offers an easy-to-use user interface that allows you to quickly generate email templates with dynamic attributes. In this article, I'll show you how I was able to integrate Email JS into my React app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along with this article, you should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Already have basic knowledge of the React library and how to create a React app. if you're new to React please visit &lt;a href="https://beta.reactjs.org/learn" rel="noopener noreferrer"&gt;reactjs.org&lt;/a&gt; or &lt;a href="https://create-react-app.dev/" rel="noopener noreferrer"&gt;create-react-app.dev/&lt;/a&gt; to get started.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Firstly, I created a new React app by running the following command in my terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app my-form-app 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;cd into the app folder and run the following command to start the development server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd my-form-app
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I opened the app.js in the src folder and went ahead to remove all the unnecessary code from it; it should look like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5n89u1h8425wzkxnegyp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5n89u1h8425wzkxnegyp.png" alt="Image description" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started.
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create an account&lt;/strong&gt;&lt;br&gt;
I created an account on &lt;a href="https://www.emailjs.com/" rel="noopener noreferrer"&gt;Emailjs.com&lt;/a&gt; website; The website interface typically looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9uetxcajwfsuf9csyj9i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9uetxcajwfsuf9csyj9i.png" alt="Image description" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;once done, confirmed my email, and logged in.&lt;br&gt;
After login, I was taken to the admin dashboard, which will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pz4roixkz77b01hayax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pz4roixkz77b01hayax.png" alt="Image description" width="800" height="437"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Configure Your Email JS Setting&lt;/strong&gt;&lt;br&gt;
Next, I click on the “Add New Service” Icon in order to  to create and add an email service that will be used to send emails. When you click on it, a screen asking you to select your preferred email service will appear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgt1pfdvu546pab8uftv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgt1pfdvu546pab8uftv.png" alt="Image description" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From here, I clicked on Connect Account; where redirected me to my email provider to confirm the connection. once finalized, I finish this step by clicking on Create Service and the email service is all set.&lt;/p&gt;

&lt;p&gt;The new email service on the home page is as shown below:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpsaww9ogykgbg3sfkwr5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpsaww9ogykgbg3sfkwr5.png" alt="Image description" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create and customize an email template&lt;/strong&gt;&lt;br&gt;
after creating an email service the next thing was to create an email template.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpfmhn74xjkrs763730zi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpfmhn74xjkrs763730zi.png" alt="Image description" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To do this, click on “Email Templates” and then “Create New Template”. This is what it will look like:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fraf1p14pcj7lt5wn10w2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fraf1p14pcj7lt5wn10w2.png" alt="Image description" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I customised it to be like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1s4qufug3k9of5ozzyg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1s4qufug3k9of5ozzyg.png" alt="Image description" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The curly brackets are dynamic parameters, To reflect what is sent to EmailJs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;from_name&lt;/code&gt;: this has to do with the name of the person sending the email through the contact form.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;to_name&lt;/code&gt;: this has to do with the receiver's name. That's me since I'm the owner of the Gmail account to which the email is being sent to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;message&lt;/code&gt;: this has to do with the sender’s message.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;reply_to&lt;/code&gt;: this has to do with the sender’s email.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;phone_number&lt;/code&gt;: while this is the sender’s number.&lt;br&gt;
All these parameters will be used during the implementation in the react app&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Side Note:&lt;br&gt;
you can move on to the next tab ' Auto-Reply ' and enable autoreply back to the sender; Make sure to tick the box mentioning Auto-Reply if you want a reply sent to your user.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4vi2i7g463l3schegd7b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4vi2i7g463l3schegd7b.png" alt="Image description" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Implementation&lt;/strong&gt;&lt;br&gt;
Now I'm ready to implement emailjs form handling functionality in my react app. Please check the official emailjs &lt;a href="https://www.emailjs.com/docs/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for detailed explanations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install the Email JS React Library&lt;/strong&gt;&lt;br&gt;
This provides an easy way to integrate Email JS into your React application. It can be installed using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @emailjs/browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next is to import the following at the top of your app.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react';
import emailjs from "@emailjs/browser";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After importing I created a basic react form which should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div className="container"&amp;gt;
        &amp;lt;h1&amp;gt;Contact page&amp;lt;/h1&amp;gt;
        &amp;lt;form className="form" onSubmit={onSubmit}&amp;gt;
          &amp;lt;div className="form-group"&amp;gt;
            &amp;lt;input
              className="form-control"
              type="text"
              name="from_name"
              value={from_name}
              onChange={onChange}
              id="from_name"
              placeholder="Enter Fullname"
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="form-group"&amp;gt;
            &amp;lt;input
              className="form-control"
              type="text"
              name="reply_to"
              value={reply_to}
              onChange={onChange}
              id="reply_to"
              placeholder="Enter Email"
            /&amp;gt;

          &amp;lt;/div&amp;gt;
          &amp;lt;div className="form-group"&amp;gt;
            &amp;lt;input
              className="form-control"
              type="tel"
              name="phone_number"
              value={phone_number}
              onChange={onChange}
              id="phone_number"
              placeholder="Enter Phone Number"
            /&amp;gt;

          &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="form-group"&amp;gt;
            &amp;lt;textarea
              className="form-control"
              name="message"
              value={message}
              onChange={onChange}
              id="message"
              placeholder="Enter Message"
            &amp;gt;&amp;lt;/textarea&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;button type="submit" id="button"&amp;gt;
            Submit
          &amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a few things worth mentioning in the &lt;code&gt;form&lt;/code&gt; above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
The &lt;code&gt;required&lt;/code&gt; attribute is for basic validation. which prevents incomplete forms to be submitted by the user.&lt;/li&gt;
&lt;li&gt;
The &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;value&lt;/code&gt; attributes in the input fields are the same as the dynamic parameters created in the email templates.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the opening tag of the form, the &lt;code&gt;onSubmit&lt;/code&gt; attribute would trigger the onSubmit function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I created a state &lt;code&gt;formData&lt;/code&gt; that is an object which tracks all the changes happening in the form.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const [formData, setFormData] = useState({
    from_name: "",
    reply_to: "",
    phone_number: "",
    company_name: "",
    message: ""
  });
  const { from_name, reply_to, phone_number, company_name, message } = formData;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
In the&lt;code&gt;onChange&lt;/code&gt; attribute I set the formData by first using a spread operator &lt;code&gt;...&lt;/code&gt; to list the items in the state object and then match the input ID with the input value by using &lt;code&gt;e.target&lt;/code&gt; so as to capture and update the changes in the input fields.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const onChange = (e) =&amp;gt; {
    setFormData({
      ...formData,
      [e.target.id]: e.target.value
    });
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
Check out the onSubmit function below.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const onSubmit = (e) =&amp;gt; {
    e.preventDefault();

    formData["to_name"] = "Blessing Peter";

    const YOUR_SERVICE_ID = "service_k5uanup";
    const YOUR_TEMPLATE_ID = "template_1i82n0k";
    const YOUR_PUBLIC_KEY = "ZTxRbsirc1MJiUsQ9";

    emailjs.send(YOUR_SERVICE_ID, YOUR_TEMPLATE_ID, formData, YOUR_PUBLIC_KEY).then(
      () =&amp;gt; {
        console.log("Email Sent")
        setFormData({
          from_name: "",
          reply_to: "",
          phone_number: "",
          company_name: "",
          message: ""
        });
      },
      (error) =&amp;gt; {
        console.log(JSON.stringify(error));
      });
    console.log(formData);
  };

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the breakdown to understand it better:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;e&lt;/code&gt; is passed as a parameter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;e.preventDefault()&lt;/code&gt; would prevent the page from being reloaded when submitted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since the formData state is an object, and objects are key collection items I created a new key&lt;code&gt;["to_name"]&lt;/code&gt; and gave it a value &lt;code&gt;"Blessing Peter"&lt;/code&gt;. &lt;strong&gt;Note that&lt;/strong&gt; &lt;code&gt;["to_name"]&lt;/code&gt; is also a dynamic parameters created in the email templates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;emailjs.sendForm()&lt;/code&gt; takes four parameters,&lt;code&gt;a service ID&lt;/code&gt; (that was created earlier), a template ID (also created earlier and can be seen in the email template settings), and a Public Key (that is seen in the account settings ) all of which values I saved in a const variable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since &lt;code&gt;emailjs.sendForm()&lt;/code&gt; is a promise (asynchronous) I follow it with &lt;code&gt;.then&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the .then I console.log &lt;code&gt;email Sent&lt;/code&gt; and also reset the formData state to an empty string &lt;code&gt;""&lt;/code&gt; so that the form is cleared if successful or the error if unsuccessful (since the error is coming from the server JSON.stringify turns it to a string).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;That’s it&lt;/strong&gt;, we can now receive emails straight from our app without creating a backend!&lt;/p&gt;

&lt;p&gt;you can check out the replit link &lt;a href="https://replit.com/@blesyn/Emailjs#src/App.jsx" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading! I hope you learned a thing or two ❤️&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>software</category>
      <category>productivity</category>
      <category>socialmedia</category>
    </item>
    <item>
      <title>How I Built A React App (myGithub) That Uses The GitHub API To Fetch Users Portfolio And Repos</title>
      <dc:creator>Blessing Peters</dc:creator>
      <pubDate>Tue, 10 Jan 2023 19:43:02 +0000</pubDate>
      <link>https://forem.com/blessingpeters/how-i-built-a-react-app-mygithub-that-uses-the-github-api-to-fetch-users-portfolio-and-repos-4h0n</link>
      <guid>https://forem.com/blessingpeters/how-i-built-a-react-app-mygithub-that-uses-the-github-api-to-fetch-users-portfolio-and-repos-4h0n</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;My Github is a React app built by implementing an API fetch of my Github Portfolio and repos. it allows users to easily search for their favorite repos on my profile. recently i added a search feature where users can also search for other github users profile and Repos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aplication Overview
&lt;/h2&gt;

&lt;p&gt;in order to complete this project i was able to achieve the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Implemented an API fetch of my GitHub Portfolio showing a page with a list of all your repositories on GitHub&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implemented &lt;strong&gt;pagination&lt;/strong&gt; for the repo list&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created another linking page that shows the data for a single repo clicked from the list of repositories using &lt;strong&gt;nested routes&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implemented proper SEO, Error Boundary (showing a page to test the error boundary), and 404 pages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Additionally i added search bar from which users can search for other github users.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The tools for local development is:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Node&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node Package Manager (npm)&lt;br&gt;
To get started these tools must be installed on your computer. click &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;nodejs.org&lt;/a&gt; to download them&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Process
&lt;/h2&gt;

&lt;p&gt;Firstly, after setting up my environment, I created a new React app by first creating a folder called myGithub and then running the following command in my terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a react app here or in the current directory.  without creating a whole other folder within the folder, then &lt;code&gt;npm start&lt;/code&gt; to run my application&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I implemented the API fetch&lt;/strong&gt;&lt;br&gt;
I started this project by implementing an API fetch of my GitHub portfolio in Home.jsx. By first Importing useEffect and useState from react.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useEffect } from "react";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I created two useState to store the responses from the API fetch. one to store the api response from fetching the user profile data and the other to store the response from fetching the repos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const [user, setUser] = useState({});
    const [repos, setRepos] = useState([]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;i created a variable &lt;code&gt;url&lt;/code&gt; to store the API url and &lt;code&gt;token&lt;/code&gt; to store my github generated API key that had already been hidden in the &lt;code&gt;.env.local&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const url = "https://api.github.com";
  const token = process.env.REACT_APP_GITHUB_API_KEY;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that i created 2 asynchronous function called &lt;code&gt;getProfile&lt;/code&gt; and&lt;code&gt;getRepo&lt;/code&gt; that made the API request to the GitHub API to fetch the user profile data and repo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 // fetching MY PROFILE
    const getProfile = async () =&amp;gt; {
      const response = await fetch(`${url}/users/ble-syn`, {
        headers: {
          Authorization: `token ${token}`,
        },
      });
      const data = await response.json();
      setUser(data);
      setLoading(false);
    };

  // fetching MY REPOS 
  const getRepo = async () =&amp;gt; {

    const response = await fetch(`${url}/users/ble-syn/repos`, {
      headers: {
        Authorization: `token ${token}`,
      },
    });
    const data = await response.json();
    setRepos(data);
    setLoading(false);
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I called &lt;code&gt;getProfile&lt;/code&gt; and&lt;code&gt;getRepo&lt;/code&gt; inside of a useEffect hook, and passed in an empty array as its dependency, so that the application makes the fetch request only once when it loads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; useEffect(() =&amp;gt; {
    getProfile();
    getRepo();
  }, []);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the &lt;code&gt;user&lt;/code&gt; state created earlier is an object, I destructure it with dot notation to extract the data and render them in Githubprofile.jsx.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          &amp;lt;img className="profile-img" src={profile.avatar_url} alt="" /&amp;gt;
          &amp;lt;h2&amp;gt;{profile.name}&amp;lt;/h2&amp;gt;
          &amp;lt;p&amp;gt;{profile.login}&amp;lt;/p&amp;gt;
          &amp;lt;p&amp;gt;{profile.bio}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;N/B it is called &lt;strong&gt;profile&lt;/strong&gt; in the code above because i created a seperate component called GithubProfile.jsx and passed the &lt;code&gt;user&lt;/code&gt; state created in the home.jsx as a &lt;a href="https://reactjs.org/docs/components-and-props.html" rel="noopener noreferrer"&gt;prop&lt;/a&gt; where i named it &lt;strong&gt;profile&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;also, since the &lt;code&gt;repos&lt;/code&gt; state  created too is an array of objects. I iterated through repos using the JavaScript map() method, destructured the object to extract the data and render them in repos.jsx.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementing Pagination&lt;/strong&gt;&lt;br&gt;
Pagination is used to break up a block of content into navigable pages on a webpage. Where a user can use links such as "next", "previous", and page numbers to navigate between pages&lt;/p&gt;

&lt;p&gt;Aside from making it easier to see information, it also helps when loading data from a server. Using pagination, you can decide to only load a fixed number of items each time when the user decides to see them. This helps save time and avoid information overload on a page.&lt;/p&gt;

&lt;p&gt;I implemented pagination using useState by first creating 2 states &lt;code&gt;currentPage&lt;/code&gt; which i gave an initial state of &lt;strong&gt;1&lt;/strong&gt; and &lt;code&gt;repoPerPage&lt;/code&gt;, which specified the number of items that will be displayed on each page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const [currentPage, setCurrentPage] = useState(1);
 const [repoPerPage] = useState(4);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  // Pagination logic
  const indexOfLastNumber = currentPage * repoPerPage;
  const indexOfFirstNumber = indexOfLastNumber - repoPerPage;
  const currentRepo = repos.slice(indexOfFirstNumber, 
  indexOfLastNumber);
  const numberOfPages = Math.ceil(repos.length / repoPerPage);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Pagination({ numberOfPages, currentPage, setCurrentPage }) {
  const [disabledPrev, setDisabledPrev] = useState(true);
  const [disabledNext, setDisabledNext] = useState(true);

  const pageNum = [...Array(numberOfPages + 1).keys()].slice(1);

  const nextPage = () =&amp;gt; {
    if (currentPage !== numberOfPages) setCurrentPage(currentPage + 1);
  };
  const prevPage = () =&amp;gt; {
    if (currentPage !== 1) setCurrentPage(currentPage - 1);
  };

  useEffect(() =&amp;gt; {
    if (currentPage &amp;gt; 1) {
      setDisabledPrev(false);
    } else {
      setDisabledPrev(true);
    }

    if (currentPage === numberOfPages) {
      setDisabledNext(true);
    } else {
      setDisabledNext(false);
    }
  }, [currentPage, numberOfPages]);
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;section className="pagination"&amp;gt;
        &amp;lt;div onClick={prevPage} className={disabledPrev ? "disabled" : "prev"}&amp;gt;
          &amp;lt;LeftArrow /&amp;gt;
          &amp;lt;p&amp;gt; Previous&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div className="pagination-num flex"&amp;gt;
          {pageNum.map((num) =&amp;gt; (
            &amp;lt;div key={num}&amp;gt;
              &amp;lt;p
                onClick={() =&amp;gt; setCurrentPage(num)}
                className="pagination-child"
              &amp;gt;
                {num}
              &amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
          ))}
        &amp;lt;/div&amp;gt;
        &amp;lt;div onClick={nextPage} className={disabledNext ? "disabled" : "next"}&amp;gt;
          &amp;lt;p&amp;gt;Next &amp;lt;/p&amp;gt;
          &amp;lt;RightArrow /&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/section&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Pagination;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Implemention React-router, Nested Routes and Error Boundary&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Firstly i installed the necessary dependencies needed to implement react-router, nested routes and error boundary by running the following commands in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save react-router-dom
npm install --save react-error-boundary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;react-router-dom: used for routing pages in the app&lt;/li&gt;
&lt;li&gt;react-error-boundary: for handling errors that occur within React components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For React Router I created 3 routes which include,  the home page(which has the nested routes),the error page, not found / 404 page.&lt;/p&gt;

&lt;p&gt;Then I imported BrowserRouter from react-router-dom.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { BrowserRouter as Router, Routes, Route} from "react-router-dom";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The outer component is Routes which wrapped the 3 Route component&lt;/p&gt;

&lt;p&gt;The Route should have the path and element attributes, the path for the &lt;strong&gt;404 page&lt;/strong&gt; is an asterisk.&lt;/p&gt;

&lt;p&gt;The path attributes take in either the absolute or relative path in the string.&lt;br&gt;
The element attributes take in the component that you want to render on the path accustomed to the Route.&lt;/p&gt;

&lt;p&gt;check out the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Router&amp;gt;
      &amp;lt;Routes&amp;gt;
        &amp;lt;Route path="/" element={&amp;lt;Home /&amp;gt;}&amp;gt;
          &amp;lt;Route path="/repo/:id" element={&amp;lt;RepoPage/&amp;gt;} /&amp;gt;
        &amp;lt;/Route&amp;gt;
        &amp;lt;Route path="/errortestpage" element={&amp;lt;ErrorTestPage /&amp;gt;}/&amp;gt;
        &amp;lt;Route path="/not-found" element={&amp;lt;NotFound /&amp;gt;} /&amp;gt;
        &amp;lt;Route path="*" element={&amp;lt;Navigate to="/not-found" /&amp;gt;} /&amp;gt;
      &amp;lt;/Routes&amp;gt;
    &amp;lt;/Router&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nested Routes&lt;/strong&gt;&lt;br&gt;
nested routing is having a Route component inside the opening and closing tag of another Route component as shown below&lt;/p&gt;

&lt;p&gt;I embedded a child Route &lt;code&gt;repo page&lt;/code&gt; in between the home page Route which I also provided with a path and an element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Route path="/" element={&amp;lt;Home /&amp;gt;}&amp;gt;
          &amp;lt;Route path="/repo/:id" element={&amp;lt;RepoPage/&amp;gt;} /&amp;gt;
&amp;lt;/Route&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Error Boundary&lt;/strong&gt;&lt;br&gt;
Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI instead of the component tree that crashed.&lt;/p&gt;

&lt;p&gt;I imported ErrorBoundary from react-error-boundary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ErrorBoundary } from 'react-error-boundary'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;created a fallback component called errorFallback that displays instead of the error breaking the entire app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function ErrorFallback({ error }) {
  return (
    &amp;lt;div role="alert"&amp;gt;
      &amp;lt;p&amp;gt;Something went wrong:&amp;lt;/p&amp;gt;
      &amp;lt;pre style={{ color: 'red' }}&amp;gt;{error.message}&amp;lt;/pre&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used the ErrorBoundary component provided by react-error-boundary to wrap the components that i want to handle errors for. This component will catch any errors that occur within the wrapped components and display a fallback UI to the user instead of crashing the whole app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;ErrorBoundary FallbackComponent={ErrorFallback}&amp;gt; 
      &amp;lt;Repos  /&amp;gt; 
  &amp;lt;/ErrorBoundary&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Additional feature
&lt;/h2&gt;

&lt;p&gt;finally i was able to add a search feature where people can find other github users and display their profile and repos as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fooqwdebp58174bgk5x70.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fooqwdebp58174bgk5x70.png" alt="Image description" width="800" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I achieved this by following almost the same process in the API fetch implementation section. which includes&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;creating a state to store the user profile data and user repos&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;creating 2 asynchronous function that &lt;code&gt;handleSearchuser&lt;/code&gt; and &lt;code&gt;handleSearchRepo&lt;/code&gt; that make the API calls to fetch the Users profile data and repo.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  // NEW FEATURE: Searching for Other GitHub Users
  const handleSearch = async (e) =&amp;gt; {
    e.preventDefault();
    if (search === "") return;
    await handleSearchUser();
    await handleSearchRepo();
  };

  const handleSearchUser = async () =&amp;gt; {
    const response = await fetch(`${url}/users/${search}`, {
      headers: {
        Authorization: `token ${token}`,
      },
    });
    const data = await response.json();
    setUser(data);
    setLoading(false);
  };

  const handleSearchRepo = async () =&amp;gt; {
    const response = await fetch(`${url}/users/${search}/repos`, {
      headers: {
        Authorization: `token ${token}`,
      },
    });

    const data = await response.json();
    setRepos(data);
    setLoading(false);
    console.log(data);
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;created a handleSearch that receives and stores the response from &lt;code&gt;handleSearchuser&lt;/code&gt; and &lt;code&gt;handleSearchRepo&lt;/code&gt; functions
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const handleSearch = async (e) =&amp;gt; {
    e.preventDefault();
    if (search === "") return;
    await handleSearchUser();
    await handleSearchRepo();
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally i  created a form that takes in an input and a button, an onchange event is given on the input so as to track the input and an onSubmit event on the form to trigger the &lt;code&gt;handleSearch&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form onSubmit={handleSearch}&amp;gt;
 &amp;lt;input className="search-input" type="text" value={search} onChange={(e)=&amp;gt;setSearch(e.target.value)} placeholder="Search For a Github User" /&amp;gt;
 &amp;lt;button className="search-btn"&amp;gt;&amp;lt;p&amp;gt;Search&amp;lt;/p&amp;gt;  &amp;lt;RightArrow className="btn-arrow" /&amp;gt;&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  conclusion.
&lt;/h2&gt;

&lt;p&gt;Thank you for taking your time to read this article and maybe learned something.&lt;br&gt;
I loved working on this as i was able to learn and implement various React concepts.  Checkout the source code in my &lt;a href="https://github.com/ble-syn/myGithub" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; and the &lt;a href="https://my-github-ble-syn.vercel.app/" rel="noopener noreferrer"&gt;link&lt;/a&gt; to the live site.&lt;/p&gt;

&lt;p&gt;Thanks Again❤️&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
  </channel>
</rss>
