Mastering useState: Creating a Github profile catalog using GitHub API
What you should Know:
- Knowledge of Javascript
- Basic knowledge of React
- Basic knowledge of React Hooks, especially useState() & useEffect
React hooks are the modern way to deal with application state and lifecycle events within components. Hooks have been introduced to make React code cleaner.
React has multiple hooks to carry out different operations. We have majorly the useState and useEffect hooks. It’s necessary that every aspiring React developer should be knowledgeable in these hooks, especially these 2.
useState and useEffect are destructured from react.
import { useState, useEffect } from “react
We initialize our state by calling useState in our function component.
useState accepts an initial state and returns two values:
- The current state.
- A function that updates the state.
import { useState } from "react";
function newValue() {
const [value, setValue] = useState(0);
return (
<h1>{value}</h1> //prints zero
)
}
The useEffect hook allows us to respond to changes in the component lifecycle. The component lifecycle refers to a set of events that occur from the time a component is mounted to the DOM until it is removed. It uses a dependency array to determine how many times it renders.
One of the benefits of useState is used to fetch data from an Api endpoint
We will be using the Github Api to create collage of Github contributors. (This idea is extracted from CoddingAddict).
If we open the link(https://api.github.com/users) on the web browser, You would get this:
[
{
"login": "mojombo",
"id": 1,
"node_id": "MDQ6VXNlcjE=",
"avatar_url": "https://avatars.githubusercontent.com/u/1?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/mojombo",
"html_url": "https://github.com/mojombo",
"followers_url": "https://api.github.com/users/mojombo/followers",
"following_url": "https://api.github.com/users/mojombo/following{/other_user}",
"gists_url": "https://api.github.com/users/mojombo/gists{/gist_id}",
"starred_url": "https://api.github.com/users/mojombo/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/mojombo/subscriptions",
"organizations_url": "https://api.github.com/users/mojombo/orgs",
"repos_url": "https://api.github.com/users/mojombo/repos",
"events_url": "https://api.github.com/users/mojombo/events{/privacy}",
"received_events_url": "https://api.github.com/users/mojombo/received_events",
"type": "User",
"site_admin": false
},
{
"login": "defunkt",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars.githubusercontent.com/u/2?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/defunkt",
"html_url": "https://github.com/defunkt",
"followers_url": "https://api.github.com/users/defunkt/followers",
"following_url": "https://api.github.com/users/defunkt/following{/other_user}",
"gists_url": "https://api.github.com/users/defunkt/gists{/gist_id}",
"starred_url": "https://api.github.com/users/defunkt/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/defunkt/subscriptions",
"organizations_url": "https://api.github.com/users/defunkt/orgs",
]
An array of objects. We will to accessing each of these data and will be displaying it very soon.
Declare your function components.
function GithubUsers() {
const [users, setUsers] = useState(0); //we’ll be calling the data we get from the api “users”
//We’ll be accessing the data. Because it’s an API is an asynchronous function
const getUsers = async () => {
const res = await fetch(url);
const users = await res.json();
setUsers(users)
}
useEffect(() => {
getUsers();
}, []);//[]The dependency array
return (
<>
<h3>Github users</h3>
<ul>
{users.map((user) => { //map out each objects
const { id, login, avatar_url, html_url } = user;
return (
<li key={id}> //destructure each item from the object
<img src={avatar_url} alt={login} />
<div>
<h4>{login}</h4>
<a href={html_url}>profile</a>
</div>
</li>
);
})}
</ul>
</>
)
};
To make each profile more beautiful. You can input this CSS property.
:root {
/* dark shades of primary color*/
--clr-primary-1: hsl(205, 86%, 17%);
--clr-primary-2: hsl(205, 77%, 27%);
--clr-primary-3: hsl(205, 72%, 37%);
--clr-primary-4: hsl(205, 63%, 48%);
/* primary/main color */
--clr-primary-5: hsl(205, 78%, 60%);
/* lighter shades of primary color */
--clr-primary-6: hsl(205, 89%, 70%);
--clr-primary-7: hsl(205, 90%, 76%);
--clr-primary-8: hsl(205, 86%, 81%);
--clr-primary-9: hsl(205, 90%, 88%);
--clr-primary-10: hsl(205, 100%, 96%);
/* darkest grey - used for headings */
--clr-grey-1: hsl(209, 61%, 16%);
--clr-grey-2: hsl(211, 39%, 23%);
--clr-grey-3: hsl(209, 34%, 30%);
--clr-grey-4: hsl(209, 28%, 39%);
/* grey used for paragraphs */
--clr-grey-5: hsl(210, 22%, 49%);
--clr-grey-6: hsl(209, 23%, 60%);
--clr-grey-7: hsl(211, 27%, 70%);
--clr-grey-8: hsl(210, 31%, 80%);
--clr-grey-9: hsl(212, 33%, 89%);
--clr-grey-10: hsl(210, 36%, 96%);
--clr-white: #fff;
--clr-red-dark: hsl(360, 67%, 44%);
--clr-red-light: hsl(360, 71%, 66%);
--clr-green-dark: hsl(125, 67%, 44%);
--clr-green-light: hsl(125, 71%, 66%);
--clr-black: #222;
--transition: all 0.3s linear;
--spacing: 0.1rem;
--radius: 0.25rem;
--light-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
--dark-shadow: 0 5px 15px rgba(0, 0, 0, 0.4);
--max-width: 1170px;
--fixed-width: 450px;
--clr-orange-1: hsl(12, 83%, 98%);
--clr-orange-2: hsl(14, 91%, 95%);
--clr-orange-3: hsl(12, 89%, 89%);
--clr-orange-4: hsl(13, 87%, 82%);
--clr-orange-5: hsl(13, 88%, 68%);
--clr-orange-6: hsl(13, 88%, 55%);
--clr-orange-7: hsl(13, 74%, 49%);
--clr-orange-8: hsl(13, 74%, 33%);
--clr-orange-9: hsl(13, 73%, 25%);
--clr-orange-10: hsl(13, 73%, 16%);
}
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
background: var(--clr-grey-10);
color: var(--clr-grey-1);
line-height: 1.5;
font-size: 0.875rem;
}
ul {
list-style-type: none;
}
a {
text-decoration: none;
}
h1,
h2,
h3,
h4 {
letter-spacing: var(--spacing);
text-transform: capitalize;
line-height: 1.25;
margin-bottom: 0.75rem;
}
h1 {
font-size: 3rem;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1.25rem;
}
h4 {
font-size: 0.875rem;
}
p {
margin-bottom: 1.25rem;
color: var(--clr-grey-5);
}
@media screen and (min-width: 800px) {
h1 {
font-size: 4rem;
}
h2 {
font-size: 2.5rem;
}
h3 {
font-size: 1.75rem;
}
h4 {
font-size: 1rem;
}
body {
font-size: 1rem;
}
h1,
h2,
h3,
h4 {
line-height: 1;
}
}
/* global classes */
/* section */
.section,
.container {
width: 90vw;
margin: 0 auto;
max-width: var(--max-width);
}
@media screen and (min-width: 992px) {
.section {
width: 95vw;
}
}
.container {
text-align: center;
margin-top: 5rem;
}
.btn {
display: inline-block;
background: var(--clr-primary-5);
color: var(--clr-white);
padding: 0.25rem 0.75rem;
border-radius: var(--radius);
border-color: transparent;
text-transform: capitalize;
font-size: 1rem;
letter-spacing: var(--spacing);
margin-top: 2rem;
margin-left: 0.5rem;
margin-right: 0.5rem;
cursor: pointer;
transition: var(--transition);
}
.btn:hover {
background: var(--clr-primary-1);
color: var(--clr-primary-5);
}
.users {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin: 3rem auto;
}
Make sure you import the CSS file at the top of your file
import "./bish.css";
After the import, add this CSS class “users” at the
- tag at this point in the functional component.
<h3>Github users</h3>
<ul className="users">//Just add the className
Here’s what you will achieve after this