momin-riyadh 5 years ago
commit 79b25051fc

@ -52,6 +52,7 @@ This section covers prerequisites to get started with React. You should have a g
If you have the skills mentioned above, you will enjoy doing React. The 30 Days Of React challenge contains everything you need to know about react. In every section, it has some exercises and mini-projects, and it is recommended to work on them. This 30 Days Of React challenge will help you learn the latest version of React and the old version, step by step. The topics are broken down into 30 days, where each day contains several topics with easy-to-understand explanations, real-world examples and many hands-on exercises.
This challenge is designed for beginners and professionals who want to build a web application using React and JavaScript.
Once in a while you may need different dummy data to work with React. You can use the following [dummy data generator](https://www.30daysofreact.com/dummy-data) to generate different data.
### 1. What is React?
@ -115,7 +116,7 @@ const welcome = <h1>Welcome to 30 Days of React Challenge</h1>
const data = <small>Oct 2, 2020</small>
```
The above strange looking code seems like JavaScript and it seems like , but it is not JavaScript and it seems like HTML but not completely an HTML element. It is a mix of JavaScript and an HTML elements. JSX can allow us to use HTML in JavaScript. The HTML element in the JSX above is _h1_ and _small_.
The above strange looking code seems like JavaScript and it seems like , but it is not JavaScript and it seems like HTML but not completely an HTML element. It is a mix of JavaScript and an HTML elements. JSX can allow us to use HTML in JavaScript. The HTML element in the JSX above is _h1_ and _small_.
#### JSX Element

@ -1086,7 +1086,7 @@ We will cover propTypes in detail in other sections.
## Exercises: Level 3
1. Use the given hexadecimal color generator in the example to create these random colors
1. Use the given hexadecimal color generator in the example to create these random colors. If you don't know how to generate the hexadecimal color you can use [dummy data generator](https://www.30daysofreact.com/dummy-data)
![Hexadecimal colors](../images/hexadecimal_color_exercise.png)

@ -358,11 +358,6 @@ class App extends Component {
}
renderCountries = () => {
return this.state.data.map((country) => {
const languageOrLanguages =
country.languages.length > 1 ? 'Langauges' : 'Language'
const formatLanguages = country.languages
.map(({ name }) => name)
.join(', ')
return (
<div>
<div>
@ -371,10 +366,6 @@ class App extends Component {
</div>
<div>
<h1>{country.name}</h1>
<p>Capital: {country.capital}</p>
<p>
{languageOrLanguages}: {formatLanguages}
</p>
<p>Population: {country.population}</p>
</div>
</div>

@ -30,11 +30,6 @@ class App extends Component {
}
renderCountries = () => {
return this.state.data.map((country) => {
const languageOrLanguages =
country.languages.length > 1 ? 'Langauges' : 'Language'
const formatLanguages = country.languages
.map(({ name }) => name)
.join(', ')
return (
<div>
<div>
@ -43,10 +38,6 @@ class App extends Component {
</div>
<div>
<h1>{country.name}</h1>
<p>Capital: {country.capital}</p>
<p>
{languageOrLanguages}: {formatLanguages}
</p>
<p>Population: {country.population}</p>
</div>
</div>

@ -1,4 +1,4 @@
# 30 Days of React App: Day 19
# 30 Days of React App: Day 18
In the project directory, you can run to start the project

@ -2,20 +2,7 @@ import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import axios from 'axios'
const Country = ({
country: { name, capital, flag, languages, population, currency },
}) => {
const formatedCapital =
capital.length > 0 ? (
<>
<span>Capital: </span>
{capital}
</>
) : (
''
)
const formatLanguage = languages.length > 1 ? `Languages` : `Language`
console.log(languages)
const Country = ({ country: { name, flag, population } }) => {
return (
<div className='country'>
<div className='country_flag'>
@ -23,18 +10,9 @@ const Country = ({
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.map((language) => language.name).join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
</p>
<p>
<span>Currency: </span>
{currency}
{population}
</p>
</div>
</div>

@ -210,20 +210,7 @@ If we use async and await we handle the error using try and catch. Let's apply a
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
const Country = ({
country: { name, capital, flag, languages, population, currency },
}) => {
const formatedCapital =
capital.length > 0 ? (
<>
<span>Capital: </span>
{capital}
</>
) : (
''
)
const formatLanguage = languages.length > 1 ? `Languages` : `Language`
console.log(languages)
const Country = ({ country: { name, flag, population } }) => {
return (
<div className='country'>
<div className='country_flag'>
@ -231,14 +218,9 @@ const Country = ({
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.map((language) => language.name).join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
{population}
</p>
<p>
<span>Currency: </span>
@ -309,17 +291,6 @@ import axios from 'axios'
const Country = ({
country: { name, capital, flag, languages, population, currency },
}) => {
const formatedCapital =
capital.length > 0 ? (
<>
<span>Capital: </span>
{capital}
</>
) : (
''
)
const formatLanguage = languages.length > 1 ? `Languages` : `Language`
console.log(languages)
return (
<div className='country'>
<div className='country_flag'>
@ -327,19 +298,11 @@ const Country = ({
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.map((language) => language.name).join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
</p>
<p>
<span>Currency: </span>
{currency}
{population}
</p>
>
</div>
</div>
)
@ -393,20 +356,7 @@ import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import axios from 'axios'
const Country = ({
country: { name, capital, flag, languages, population, currency },
}) => {
const formatedCapital =
capital.length > 0 ? (
<>
<span>Capital: </span>
{capital}
</>
) : (
''
)
const formatLanguage = languages.length > 1 ? `Languages` : `Language`
console.log(languages)
const Country = ({ country: { name, flag, population } }) => {
return (
<div className='country'>
<div className='country_flag'>
@ -414,18 +364,9 @@ const Country = ({
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.map((language) => language.name).join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
</p>
<p>
<span>Currency: </span>
{currency}
{population}
</p>
</div>
</div>

@ -1,4 +1,4 @@
# 30 Days of React App: Day 17
# 30 Days of React App: Day 19
In the project directory, you can run to start the project

@ -1,4 +1,4 @@
# 30 Days of React App: Day 17
# 30 Days of React App: Day 20
In the project directory, you can run to start the project

@ -1,4 +1,4 @@
# 30 Days of React App: Day 17
# 30 Days of React App: Day 21
In the project directory, you can run to start the project

@ -14,7 +14,7 @@
</div>
[<< Day 21](../21_Introducing_Hooks/21_introducing_hooks.md) | [Day 23>>]()
[<< Day 21](../21_Introducing_Hooks/21_introducing_hooks.md) | [Day 23>>](../23_Fetching_Data_Using_Hooks/23_fetching_data_using_hooks.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_22.jpg)
@ -969,4 +969,5 @@ ReactDOM.render(<App />, rootElement)
Coming ..
🎉 CONGRATULATIONS ! 🎉
[<< Day 21](../21_Introducing_Hooks/21_introducing_hooks.md) | [Day 23>>]()
[<< Day 21](../21_Introducing_Hooks/21_introducing_hooks.md) | [Day 23>>](../23_Fetching_Data_Using_Hooks/23_fetching_data_using_hooks.md)

@ -1,4 +1,4 @@
# 30 Days of React App: Day 17
# 30 Days of React App: Day 22
In the project directory, you can run to start the project

@ -0,0 +1,99 @@
<div align="center">
<h1> 30 Days Of React: Fetching Data Using Hooks</h1>
<a class="header-badge" target="_blank" href="https://www.linkedin.com/in/asabeneh/">
<img src="https://img.shields.io/badge/style--5eba00.svg?label=LinkedIn&logo=linkedin&style=social">
</a>
<a class="header-badge" target="_blank" href="https://twitter.com/Asabeneh">
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/asabeneh?style=social">
</a>
<sub>Author:
<a href="https://www.linkedin.com/in/asabeneh/" target="_blank">Asabeneh Yetayeh</a><br>
<small> October, 2020</small>
</sub>
</div>
[<< Day 22](../22_Form_Using_Hooks/22_form_using_hooks.md) | [Day 24>>](../24_projects/24_projects.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_23.jpg)
- [Introducing React Hook](#introducing-react-hook)
- [Basic Hooks](#basic-hooks)
- [State Hook](#state-hook)
- [Effect Hook](#effect-hook)
- [Context Hook](#context-hook)
- [Additional Hook](#additional-hook)
- [Exercises](#exercises)
- [Exercises: Level 1](#exercises-level-1)
# Fetching Data Using Hooks
In the previous sections, you have learned how to fetch data using fetch and axios. In this section , we will use the useEffect hook to fetch data. We can use fetch or axios but I prefer to use axios. In React hooks, you don't have to use componentDidMount life cycle separately to fetch data. The useEffect has incorporate the React life cycle methods(mounting, updating and unmounting). Let's convert the code we wrote on day 18 to React hooks. We need to import the useEffect from react. The useEffect takes to argument that is a callback and an array. If the array is empty it behaves as componentDidMount life cycle where if the array has other properties, it will behave as updating too.
```js
import React, { useState, useEffect } from 'react'
import axios from 'axios'
import ReactDOM, { findDOMNode } from 'react-dom'
const Country = ({ country: { name, flag, population } }) => {
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>
<span>Population: </span>
{population}
</p>
</div>
</div>
)
}
const App = (props) => {
// setting initial state and method to update state
const [data, setData] = useState([])
useEffect(() => {
fetchData()
}, [])
const fetchData = async () => {
const url = 'https://restcountries.eu/rest/v2/all'
try {
const response = await fetch(url)
const data = await response.json()
setData(data)
} catch (error) {
console.log(error)
}
}
return (
<div className='App'>
<h1>Fetching Data Using Hook</h1>
<h1>Calling API</h1>
<div>
<p>There are {data.length} countries in the api</p>
<div className='countries-wrapper'>
{data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
# Exercises
🎉 CONGRATULATIONS ! 🎉
[<< Day 22](../22_Form_Using_Hooks/22_form_using_hooks.md) | [Day 24>>](../24_projects/24_projects.md)

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

@ -0,0 +1,5 @@
# 30 Days of React App: Day 23
In the project directory, you can run to start the project
### `npm start`

@ -0,0 +1,34 @@
{
"name": "30-days-of-react",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500|Roboto:300,400,500&display=swap"
rel="stylesheet"
/>
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>30 Days Of React App</title>
<style>
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
</html>

@ -0,0 +1,13 @@
export const tenHighestPopulation = [
{ country: 'World', population: 7693165599 },
{ country: 'China', population: 1377422166 },
{ country: 'India', population: 1295210000 },
{ country: 'United States of America', population: 323947000 },
{ country: 'Indonesia', population: 258705000 },
{ country: 'Brazil', population: 206135893 },
{ country: 'Pakistan', population: 194125062 },
{ country: 'Nigeria', population: 186988000 },
{ country: 'Bangladesh', population: 161006790 },
{ country: 'Russian Federation', population: 146599183 },
{ country: 'Japan', population: 126960000 },
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@ -0,0 +1,57 @@
import React, { useState, useEffect } from 'react'
import axios from 'axios'
import ReactDOM from 'react-dom'
const Country = ({ country: { name, flag } }) => {
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>
<span>Population: </span>
</p>
</div>
</div>
)
}
const App = (props) => {
// setting initial state and method to update state
const [data, setData] = useState([])
useEffect(() => {
fetchData()
}, [])
const fetchData = async () => {
const url = 'https://restcountries.eu/rest/v2/all'
try {
const response = await fetch(url)
const data = await response.json()
setData(data)
} catch (error) {
console.log(error)
}
}
return (
<div className='App'>
<h1>Fetching Data Using Hook</h1>
<h1>Calling API</h1>
<div>
<p>There are {data.length} countries in the api</p>
<div className='countries-wrapper'>
{data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

@ -0,0 +1,86 @@
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}

@ -0,0 +1,30 @@
<div align="center">
<h1> 30 Days Of React: Projects</h1>
<a class="header-badge" target="_blank" href="https://www.linkedin.com/in/asabeneh/">
<img src="https://img.shields.io/badge/style--5eba00.svg?label=LinkedIn&logo=linkedin&style=social">
</a>
<a class="header-badge" target="_blank" href="https://twitter.com/Asabeneh">
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/asabeneh?style=social">
</a>
<sub>Author:
<a href="https://www.linkedin.com/in/asabeneh/" target="_blank">Asabeneh Yetayeh</a><br>
<small> October, 2020</small>
</sub>
</div>
[<< Day 23](../23_Fetching_Data_Using_Hooks/23_fetching_data_using_hooks.md) | [Day 25>>](../25_Custom_Hooks/25_custom_hooks.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_24.jpg)
# Project Using React Hooks
# Exercises
1 Build the following application using [countries API](https://restcountries.eu/rest/v2/all).
[DEMO](https://www.30daysofreact.com/day-23/countries-data)
🎉 CONGRATULATIONS ! 🎉
[<< Day 23](../23_Fetching_Data_Using_Hooks/23_fetching_data_using_hooks.md) | [Day 25>>](../25_Custom_Hooks/25_custom_hooks.md)

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

@ -0,0 +1,5 @@
# 30 Days of React App: Day 24
In the project directory, you can run to start the project
### `npm start`

@ -0,0 +1,34 @@
{
"name": "30-days-of-react",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500|Roboto:300,400,500&display=swap"
rel="stylesheet"
/>
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>30 Days Of React App</title>
<style>
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
</html>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,13 @@
export const tenHighestPopulation = [
{ country: 'World', population: 7693165599 },
{ country: 'China', population: 1377422166 },
{ country: 'India', population: 1295210000 },
{ country: 'United States of America', population: 323947000 },
{ country: 'Indonesia', population: 258705000 },
{ country: 'Brazil', population: 206135893 },
{ country: 'Pakistan', population: 194125062 },
{ country: 'Nigeria', population: 186988000 },
{ country: 'Bangladesh', population: 161006790 },
{ country: 'Russian Federation', population: 146599183 },
{ country: 'Japan', population: 126960000 },
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@ -0,0 +1,57 @@
import React, { useState, useEffect } from 'react'
import axios from 'axios'
import ReactDOM from 'react-dom'
const Country = ({ country: { name, flag } }) => {
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>
<span>Population: </span>
</p>
</div>
</div>
)
}
const App = (props) => {
// setting initial state and method to update state
const [data, setData] = useState([])
useEffect(() => {
fetchData()
}, [])
const fetchData = async () => {
const url = 'https://restcountries.eu/rest/v2/all'
try {
const response = await fetch(url)
const data = await response.json()
setData(data)
} catch (error) {
console.log(error)
}
}
return (
<div className='App'>
<h1>Fetching Data Using Hook</h1>
<h1>Calling API</h1>
<div>
<p>There are {data.length} countries in the api</p>
<div className='countries-wrapper'>
{data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

@ -0,0 +1,86 @@
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,228 @@
<div align="center">
<h1> 30 Days Of React: Custom Hooks</h1>
<a class="header-badge" target="_blank" href="https://www.linkedin.com/in/asabeneh/">
<img src="https://img.shields.io/badge/style--5eba00.svg?label=LinkedIn&logo=linkedin&style=social">
</a>
<a class="header-badge" target="_blank" href="https://twitter.com/Asabeneh">
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/asabeneh?style=social">
</a>
<sub>Author:
<a href="https://www.linkedin.com/in/asabeneh/" target="_blank">Asabeneh Yetayeh</a><br>
<small> October, 2020</small>
</sub>
</div>
[<< Day 24](../24_projects/24_projects.md) | [Day 26>>](../26_Context/26_context.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_25.jpg)
# Custom Hooks
It is possible to make a custom hook on top of the available React hooks. For instance, when we fetch data we with use either fetch or axios to send an HTTP request and useEffect hooks to manage the React life cycle. Let's build useFetch custom hook on top of useEffect and useState.
We wrote this snippet of code in the previous section and we use useEffect hooks to fetch data from API. Now, let's convert this code to a custom hook. The naming convention for a custom hook is camelCase and it starts with the word use that is why we called our custom hook, useFetch.
```js
import React, { useState, useEffect } from 'react'
import axios from 'axios'
import ReactDOM, { findDOMNode } from 'react-dom'
const Country = ({ country: { name, flag, population } }) => {
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>
<span>Population: </span>
{population}
</p>
</div>
</div>
)
}
const App = (props) => {
// setting initial state and method to update state
const [data, setData] = useState([])
useEffect(() => {
fetchData()
}, [])
const fetchData = async () => {
const url = 'https://restcountries.eu/rest/v2/all'
try {
const response = await fetch(url)
const data = await response.json()
setData(data)
} catch (error) {
console.log(error)
}
}
return (
<div className='App'>
<h1>Fetching Data Using Hook</h1>
<h1>Calling API</h1>
<div>
<p>There are {data.length} countries in the api</p>
<div className='countries-wrapper'>
{data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
Create a file name useFetch.js, and import useState and useEffect. Then transfer the state, useEffect and fetchData function part of the above code to the useFetch.js.
```js
import { useState, useEffect } from 'react'
const useFetch = () => {
const [data, setData] = useState([])
const fetchData = async () => {
const url = 'https://restcountries.eu/rest/v2/all'
try {
const response = await fetch(url)
const data = await response.json()
setData(data)
} catch (error) {
console.log(error)
}
}
useEffect(() => {
fetchData()
}, [])
}
```
Then let's make the useFetch function to take a parameter. When we fetch data the only thing which changes is the API therefore let's pass a URL parameter for the function.
```js
import { useState, useEffect } from 'react'
const useFetch = (url) => {
const [data, setData] = useState([])
const fetchData = async () => {
try {
const response = await fetch(url)
const data = await response.json()
setData(data)
} catch (error) {
console.log(error)
}
}
useEffect(() => {
fetchData()
}, [])
}
export default useFetch
```
With the above code, we should manage to fetch the data but it is advisable to put the function in the useEffect and let's move the function code the useEffect.
```js
import { useState, useEffect } from 'react'
export const useFetch = (url) => {
const [data, setData] = useState([])
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url)
const data = await response.json()
setData(data)
} catch (error) {
console.log(error)
}
}
fetchData()
}, [url])
return data
}
export default useFetch
```
Now, let's combine everything and make it work.
```js
// index.js
import React, { useState, useEffect } from 'react'
import axios from 'axios'
import ReactDOM, { findDOMNode } from 'react-dom'
import useFetch from './useFetch'
const Country = ({ country: { name, flag, population } }) => {
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>
<span>Population: </span>
{population}
</p>
</div>
</div>
)
}
const App = (props) => {
const url = 'https://restcountries.eu/rest/v2/all'
const data = useFetch(url)
return (
<div className='App'>
<h1>Custom Hooks</h1>
<h1>Calling API</h1>
<div>
<p>There are {data.length} countries in the api</p>
<div className='countries-wrapper'>
{data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
The useState and useEffect hooks are most common React hooks which you use on daily bases. In addition to the basic hook, there are additional hooks which are not used often. You do not have to know how to use all the hooks. The useState, useEffect and useRef are very important hooks and it is recommended to know how to use them.
# Exercises
Note: Continue building the countries application
1 Build the following application using [countries API](https://restcountries.eu/rest/v2/all).
[DEMO](https://www.30daysofreact.com/day-23/countries-data)
🎉 CONGRATULATIONS ! 🎉
[<< Day 24](../24_projects/24_projects.md) | [Day 26>>](../26_Context/26_context.md)

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

@ -0,0 +1,5 @@
# 30 Days of React App: Day 25
In the project directory, you can run to start the project
### `npm start`

@ -0,0 +1,34 @@
{
"name": "30-days-of-react",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500|Roboto:300,400,500&display=swap"
rel="stylesheet"
/>
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>30 Days Of React App</title>
<style>
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
</html>

@ -0,0 +1,13 @@
export const tenHighestPopulation = [
{ country: 'World', population: 7693165599 },
{ country: 'China', population: 1377422166 },
{ country: 'India', population: 1295210000 },
{ country: 'United States of America', population: 323947000 },
{ country: 'Indonesia', population: 258705000 },
{ country: 'Brazil', population: 206135893 },
{ country: 'Pakistan', population: 194125062 },
{ country: 'Nigeria', population: 186988000 },
{ country: 'Bangladesh', population: 161006790 },
{ country: 'Russian Federation', population: 146599183 },
{ country: 'Japan', population: 126960000 },
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@ -0,0 +1,44 @@
import React, { useState, useEffect } from 'react'
import axios from 'axios'
import ReactDOM, { findDOMNode } from 'react-dom'
import useFetch from './useFetch'
const Country = ({ country: { name, flag, population } }) => {
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>
<span>Population: </span>
{population}
</p>
</div>
</div>
)
}
const App = (props) => {
const url = 'https://restcountries.eu/rest/v2/all'
const data = useFetch(url)
return (
<div className='App'>
<h1>Custom Hooks</h1>
<h1>Calling API</h1>
<div>
<p>There are {data.length} countries in the api</p>
<div className='countries-wrapper'>
{data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

@ -0,0 +1,86 @@
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}

@ -0,0 +1,22 @@
import { useState, useEffect } from 'react'
export const useFetch = (url) => {
const [data, setData] = useState([])
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url)
const data = await response.json()
setData(data)
} catch (error) {
console.log(error)
}
}
fetchData()
}, [url])
return data
}
export default useFetch

File diff suppressed because it is too large Load Diff

@ -0,0 +1,38 @@
<div align="center">
<h1> 30 Days Of React: Context</h1>
<a class="header-badge" target="_blank" href="https://www.linkedin.com/in/asabeneh/">
<img src="https://img.shields.io/badge/style--5eba00.svg?label=LinkedIn&logo=linkedin&style=social">
</a>
<a class="header-badge" target="_blank" href="https://twitter.com/Asabeneh">
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/asabeneh?style=social">
</a>
<sub>Author:
<a href="https://www.linkedin.com/in/asabeneh/" target="_blank">Asabeneh Yetayeh</a><br>
<small> October, 2020</small>
</sub>
</div>
[<< Day 25](../25_Custom_Hooks/25_custom_hooks.md) | [Day 27>>](../27_Ref/27_ref.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_26.jpg)
# Context
Context allow as to pass data through the component tree without having to pass props down manually to every child component at every level.
In React, data is passed top-down (parent to child) via props, but this can be cumbersome for certain types of props (e.g. locale preference, UI theme) that are required by many components within an application. Context provides a way to share values like these between components without having to explicitly pass a prop through every level of the tree.
## When to Use Context
Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language. For example, in the code below we manually thread through a “theme” prop in order to style the Button component:
The above text has been taken from [react documentation](https://reactjs.org/docs/context.html) without any change.
It seems the react documentation has pretty good information about context, you can go through the [react documentation](https://reactjs.org/docs/context.html).
# Exercises
🎉 CONGRATULATIONS ! 🎉
[<< Day 25](../25_Custom_Hooks/25_custom_hooks.md) | [Day 27>>](../27_Ref/27_ref.md)

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

@ -0,0 +1,5 @@
# 30 Days of React App: Day 25
In the project directory, you can run to start the project
### `npm start`

@ -0,0 +1,34 @@
{
"name": "30-days-of-react",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500|Roboto:300,400,500&display=swap"
rel="stylesheet"
/>
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>30 Days Of React App</title>
<style>
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
</html>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,13 @@
export const tenHighestPopulation = [
{ country: 'World', population: 7693165599 },
{ country: 'China', population: 1377422166 },
{ country: 'India', population: 1295210000 },
{ country: 'United States of America', population: 323947000 },
{ country: 'Indonesia', population: 258705000 },
{ country: 'Brazil', population: 206135893 },
{ country: 'Pakistan', population: 194125062 },
{ country: 'Nigeria', population: 186988000 },
{ country: 'Bangladesh', population: 161006790 },
{ country: 'Russian Federation', population: 146599183 },
{ country: 'Japan', population: 126960000 },
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@ -0,0 +1,44 @@
import React, { useState, useEffect } from 'react'
import axios from 'axios'
import ReactDOM, { findDOMNode } from 'react-dom'
import useFetch from './useFetch'
const Country = ({ country: { name, flag, population } }) => {
return (
<div className='country'>
<div className='country_flag'>
<img src={flag} alt={name} />
</div>
<h3 className='country_name'>{name.toUpperCase()}</h3>
<div class='country_text'>
<p>
<span>Population: </span>
{population}
</p>
</div>
</div>
)
}
const App = (props) => {
const url = 'https://restcountries.eu/rest/v2/all'
const data = useFetch(url)
return (
<div className='App'>
<h1>Custom Hooks</h1>
<h1>Calling API</h1>
<div>
<p>There are {data.length} countries in the api</p>
<div className='countries-wrapper'>
{data.map((country) => (
<Country country={country} />
))}
</div>
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

@ -0,0 +1,86 @@
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}

@ -0,0 +1,22 @@
import { useState, useEffect } from 'react'
export const useFetch = (url) => {
const [data, setData] = useState([])
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url)
const data = await response.json()
setData(data)
} catch (error) {
console.log(error)
}
}
fetchData()
}, [url])
return data
}
export default useFetch

File diff suppressed because it is too large Load Diff

@ -0,0 +1,144 @@
<div align="center">
<h1> 30 Days Of React: useRef</h1>
<a class="header-badge" target="_blank" href="https://www.linkedin.com/in/asabeneh/">
<img src="https://img.shields.io/badge/style--5eba00.svg?label=LinkedIn&logo=linkedin&style=social">
</a>
<a class="header-badge" target="_blank" href="https://twitter.com/Asabeneh">
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/asabeneh?style=social">
</a>
<sub>Author:
<a href="https://www.linkedin.com/in/asabeneh/" target="_blank">Asabeneh Yetayeh</a><br>
<small> October, 2020</small>
</sub>
</div>
[<< Day 25](../25_Custom_Hooks/25_custom_hooks.md) | [Day 27>>]()
![30 Days of React banner](../images/30_days_of_react_banner_day_27.jpg)
# useRef
In this challenge we have covered, how to handle uncontrolled input data. In this section, we will use the useRef hooks to get input data or to access any DOM element in your React application.
The useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.
In the following example, we see how to get data from input and access elements from the DOM tree using useRef hook.
## Getting Data from input
Let's get data from uncontrolled input element.
```js
import React, { useRef } from 'react'
import ReactDOM from 'react-dom'
const App = (props) => {
const ref = useRef(null)
const onClick = () => {
let value = ref.current.value
alert(value)
}
return (
<div className='App'>
<h1>How to use data from uncontrolled input using useRef</h1>
<input type='text' ref={ref} />
<br />
<button onClick={onClick}>Get Input Data</button>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
## Focus
Using the useRef we can trigger the focus event on input.
```js
import React, { useRef } from 'react'
import ReactDOM from 'react-dom'
const App = (props) => {
const ref = useRef(null)
const onClick = () => {
ref.current.focus()
}
return (
<div className='App'>
<h1>How to focus on input element useRef</h1>
<input type='text' ref={ref} />
<br />
<button onClick={onClick}>Click to Focus on input</button>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
## Getting Content from DOM tree
Don't touch the DOM when you develop a React application because React has its own way to manipulate the DOM using the virtual DOM. In case, we get interested to get some content from the DOM tree we can use the useRef hook. See the example:
```js
import React, { useRef } from 'react'
import ReactDOM from 'react-dom'
const App = (props) => {
const ref = useRef(null)
const onClick = () => {
let content = ref.current.textContent
alert(content)
console.log(content)
}
return (
<div className='App'>
<h1 ref={ref}>How to getting content from the DOM tree</h1>
<button onClick={onClick}>Getting Content</button>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
## Accessing and Styling a DOM element
We can access and style an element from the DOM tree. See the example below:
```js
import React, { useRef } from 'react'
import ReactDOM from 'react-dom'
const App = (props) => {
const ref = useRef(null)
const onClick = () => {
ref.current.style.backgroundColor = '#61dbfb'
ref.current.style.padding = '50px'
ref.current.style.textAlign = 'center'
}
return (
<div className='App'>
<h1 ref={ref}>How to style HTML from the DOM tree using useRef</h1>
<button onClick={onClick}>Style it</button>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement
```
# Exercises
1. Develop the following [application](https://www.30daysofreact.com/day-27/hexadecimal-colors). The application generates 27 hexadecimal colors by default. If the generate button get clicked it will generate another new 27 hexadecimal colors.
🎉 CONGRATULATIONS ! 🎉
[<< Day 25](../25_Custom_Hooks/25_custom_hooks.md) | [Day 27>>]()

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

@ -0,0 +1,5 @@
# 30 Days of React App: Day 25
In the project directory, you can run to start the project
### `npm start`

@ -0,0 +1,34 @@
{
"name": "30-days-of-react",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500|Roboto:300,400,500&display=swap"
rel="stylesheet"
/>
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>30 Days Of React App</title>
<style>
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
</html>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,13 @@
export const tenHighestPopulation = [
{ country: 'World', population: 7693165599 },
{ country: 'China', population: 1377422166 },
{ country: 'India', population: 1295210000 },
{ country: 'United States of America', population: 323947000 },
{ country: 'Indonesia', population: 258705000 },
{ country: 'Brazil', population: 206135893 },
{ country: 'Pakistan', population: 194125062 },
{ country: 'Nigeria', population: 186988000 },
{ country: 'Bangladesh', population: 161006790 },
{ country: 'Russian Federation', population: 146599183 },
{ country: 'Japan', population: 126960000 },
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@ -0,0 +1,20 @@
import React, { useRef } from 'react'
import ReactDOM from 'react-dom'
const App = (props) => {
const ref = useRef(null)
const onClick = () => {
ref.current.style.backgroundColor = '#61dbfb'
ref.current.style.padding = '50px'
ref.current.style.textAlign = 'center'
}
return (
<div className='App'>
<h1 ref={ref}>How to style HTML from the DOM tree using useRef</h1>
<button onClick={onClick}>Style it</button>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

@ -0,0 +1,86 @@
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}

@ -0,0 +1,21 @@
import { useState, useEffect } from 'react'
export const useFetch = (url) => {
const [data, setData] = useState([])
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url)
const data = await response.json()
setData(data)
} catch (error) {
console.log(error)
}
}
fetchData()
}, [url])
return data
}
export default useFetch

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

@ -45,6 +45,14 @@
|20|[Projects](./20_projects/20_projects.md)|
|21|[Hooks](./21_Introducing_Hooks/21_introducing_hooks.md)|
|22|[Forms Using Hook](./22_Form_Using_Hooks/22_form_using_hooks.md)|
|23|[Fetching Data Using Hooks](./23_Fetching_Data_Using_Hooks/23_fetching_data_using_hooks.md)|
|24|[Project using Hooks](./24_projects/24_projects.md)|
|25|[Custom Hooks](./25_Custom_Hooks/25_custom_hooks.md)|
|26|[Context](./26_Context/26_context.md)|
|27|[Ref](./26_Ref/26_ref.md)|
|28|[project]()|
|29|[project]()|
|30|[Conclusions]()|

Loading…
Cancel
Save