exercise-solution cleaned

pull/226/head
Zerebel 3 years ago
parent b3ee040dbd
commit cf82580772

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,771 +0,0 @@
<div align="center">
<h1> 30 Days Of React: Setting Up </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>
</div>
[<< Day 2](../02_Day_Introduction_to_React/02_introduction_to_react.md) | [Day 4 >>](../04_Day_Components/04_components.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_3.jpg)
- [Setting Up](#setting-up)
- [Node](#node)
- [Module](#module)
- [Package](#package)
- [Node Package Manager(NPM)](#node-package-managernpm)
- [Visual Studio Code](#visual-studio-code)
- [Browser](#browser)
- [Visual Studio Extensions](#visual-studio-extensions)
- [Create React App](#create-react-app)
- [Your first React App](#your-first-react-app)
- [React Boilerplate](#react-boilerplate)
- [Styles in JSX](#styles-in-jsx)
- [Injecting data to JSX elements](#injecting-data-to-jsx-elements)
- [Importing Media Objects in React](#importing-media-objects-in-react)
- [Exercises](#exercises)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# Setting Up
In the previous section, we learned about JSX and we accessed the React and ReactDOM package using CDN. However, in real projects instead of CDN you will use the create-react-app package to generate a React project starter(boilerplate). The initial _create-react-app_ was released on Jul 22, 2016. Before this time, developers used to configure webpack with a JavaScript module bundler, babel and all the necessary packages manually and this used to take half an hour or maybe more. Now, create-react-app will take care of everything and you will be in charge of only developing the product, instead of spending too much time configuring and setting up projects. Before we start using different tools, let's have a brief introduction to all the tools we are going to use in this challenge. You do not have to understand everything, but I will try to give a very short introduction to some of the tools and technologies that we use when we work with React.
## Node
Node is a JavaScript runtime environment that allows JavaScript to run on the server. Node was created in 2009. Node has played a great role for the growth of JavaScript. The React application starts by default at localhost 3000. The create-react-app has configured a node server for the React Application. That is why we need node and node modules. We will see create-react-app soon.
If you do not have node, install it. Install [node.js](https://nodejs.org/en/).
![Node download](../images/download_node.png)
After downloading double click and install
![Install node](../images/install_node.png)
We can check if node is installed on our local machine, by opening our device terminal or command prompt, and writing the following command:
```sh
asabeneh $ node -v
v12.18.0
```
## Module
A single or multiple functions, that can be exported and imported when needed, can be included in a project.
In React we do not use link to access modules or packages, instead we import the module. Let's see how to import and export a module or modules:
```js
// math.js
export const addTwo = (a, b) => a + b
export const multiply = (a, b) => a * b
export const subtract = (a, b) => a - b
export default (function doSomeMath() {
return {
addTwo,
multiply,
subtract,
}
})()
```
Now let's import the _math.js_ modules to a different file:
```js
// index.js
// to import the doSomeMath from the math.js with or without extension
import doSomeMath from './math.js'
// to import the other modules
// since these modules were not exported as default we have to desctructure
import { addTwo, multiply, subtract } from './math.js'
import * as everything from './math.js' // to import everything remaining
console.log(addTwo(5, 5))
console.log(doSomeMath.addTwo(5, 5))
console.log(everything)
```
After this, when you see _import React from 'react'_ or _import ReactDOM from 'react-dom'_ you will not be surprised.
## Package
A Package is a module or a collection of modules. For instance, React, ReactDOM are packages.
## Node Package Manager(NPM)
NPM was created in 2010. You do not need to install NPM separately - when you install node you will have also NPM. NPM is a default package manager for Node.js. It allows users to consume and distribute JavaScript modules that are available in the registry. NPM allows to create packages, use packages and distribute packages. NMP also played quite a big role in the growth of JavaScript. Currently, there is more than 350,000 packages in the NPM registry. Let's see the create-react-app on NPM registry. The number of downloads show the popularity of the package.
![NPM create-react-app](../images/npm_registry.png)
## Visual Studio Code
We will use Visual Studio Code as a code editor. [Download](https://code.visualstudio.com) and install it if you do not have one yet.
## Browser
We will use Google Chrome
## Visual Studio Extensions
You may need to install these extensions from Visual Studio Code
- Prettier
- ESLint
- Bracket Pair Colorizer
- ES7 React/Redux/GraphQL/React-Native snippets
## Create React App
To create a react project you can use one of the following ways. Let's assume you installed node. Open the command line interface (CLI), git bash or terminal on Mac or Linux. Then run the following command. I am using git bash.
```sh
Asabeneh@DESKTOP-KGC1AKC MINGW64 ~/Desktop
$ npx create-react-app name-of-your-project
```
If you do not like to write npx every time you create a project you may install create-react-app package globally in your computer using the following command.
```sh
Asabeneh@DESKTOP-KGC1AKC MINGW64 ~/Desktop
$ npm install -g create-react-app
```
After you installed create-react-app, you create a React application as follows:
```sh
Asabeneh@DESKTOP-KGC1AKC MINGW64 ~/Desktop
$ create-react-app name-of-project
```
# Your first React App
```sh
Asabeneh@DESKTOP-KGC1AKC MINGW64 ~
\$ cd Desktop/
```
```sh
Asabeneh@DESKTOP-KGC1AKC MINGW64 ~/Desktop
\$ npx create-react-app 30-days-of-react
```
```sh
Asabeneh@DESKTOP-KGC1AKC MINGW64 ~/Desktop
\$ cd 30-days-of-react/
```
```sh
Asabeneh@DESKTOP-KGC1AKC MINGW64 ~/Desktop/30-days-of-react (master)
\$ npm start
```
Now your React app should run at localhost 3000. Go to the App.js and modify the content by writing some text, you will see the latest changes on the browser.
To stop the server, press Ctr + C in the CLI.
![React Starting](../images/react_app_starting.png)
## React Boilerplate
Let's see the React boilerplate, which has been created by create-react-app. Whenever you create a new project, you run create-react-app and name of the project.
In the following React boilerplate, there are three folders: node_modules, public and src. In addition, there are .gitignore, README.md, package.json and yarn.lock. Some of you, instead of yarn.lock, you may have package-lock.json.
It is good to know these folders and files.
- node_modules - stores all the necessary node packages of the React applications.
- Public
- index.html - the only HTML file we have in the entire application
- favicon.ico - an icon file
- manifest.json - is used to make the application a progressive web app
- other images - open graph images(open graph images are images which are visible when a link share on social media)
- robots.txt - information, if the website allows web scraping
- src
- App.css, index.css - are different CSS files
- index.js - a file which allows to connect all the components with index.html
- App.js - A file where we usually import most of the presentational components
- serviceWorker.js: is used to add progressive web app features
- setupTests.js - to write testing cases
- package.json- List of packages the applications uses
- .gitignore - React boilerplate comes with git initiated, and the .gitingore allows files and folders not to be pushed to GitHub
- README.md - Markdown file to write documentation
- yarn.lock or package-lock.json - a means to lock the version of the package
![React Boilerplate](../images/react_boilerplate.png)
Now lets remove all the files, which we do not need at the moment, and leave only the files we need right now.
After removing most of the files, the structure of the boilerplate looks like this:
![React Boilerplate Cleaned](../images/react_bolier_plate_cleaned.png)
Now lets write code on index.js. First of, we should import React and ReactDOM. React allows us to write JSX and ReactDOM to render the JSX on the DOM. ReactDOM has a render method. Let's use all the JSX elements we created on Day 2. The ReactDOM render method takes two parameters, a JSX or a component and the root.
```js
//index.js
// importing the react and react-dom package
import React from 'react'
import ReactDOM from 'react-dom'
const jsxElement = <h1>This is a JSX element</h1>
const rootElement = document.getElementById('root')
ReactDOM.render(jsxElement, rootElement)
```
```html
<!-- index.html -->
<!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>
</head>
<body>
<div id="root"></div>
</body>
</html>
```
If your application is not running, go to your project folder and run the following command
```sh
Asabeneh@DESKTOP-KGC1AKC MINGW64 ~/Desktop/30-days-of-react (master)
\$ npm start
```
If you do not have any bugs, your React app will be launched on the browser.
![JSX using create react app](../images/jsx_use_create_react_app.png)
Let's write more JSX elements and render them on the browser. This expression is a JSX element which is made of h2 HTML element.
```js
const title = <h2>Getting Started React</h2>
```
Let's add more content to the previous JSX and change the name to header.
```js
const header = (
<header>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
</header>
)
```
Let's render this to the browser, in order to do so, we need ReactDOM.
```js
//index.js
// importing the react and react-dom package
import React from 'react'
import ReactDOM from 'react-dom'
const header = (
<header>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 2, 2020</small>
</header>
)
const rootElement = document.getElementById('root')
ReactDOM.render(header, rootElement)
```
![JSX using create react app](../images/rendering_more_jsx_content_create_react_app.png)
Now, lets add all the JSX we created on Day 2.
```js
//index.js
// importing the react and react-dom package
import React from 'react'
import ReactDOM from 'react-dom'
// JSX element, header
const header = (
<header>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 2, 2020</small>
</header>
)
// JSX element, main
const main = (
<main>
<p>Prerequisite to get started react.js:</p>
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
</main>
)
// JSX element, footer
const footer = (
<footer>
<p>Copyright 2020</p>
</footer>
)
// JSX element, app, a container or a parent
const app = (
<div>
{header}
{main}
{footer}
</div>
)
const rootElement = document.getElementById('root')
// we render the JSX element using the ReactDOM package
// ReactDOM has the render method and the render method takes two argument
ReactDOM.render(app, rootElement)
// or
// ReactDOM.render([header, main, footer], rootElement)
```
![JSX using create react app to render more jsx](../images/rendering_multiple_jsx_elements_create-react_app.png)
## Styles in JSX
Let's apply style to the JSX elements. We can style JSX either using inline, internal or external CSS styles. Now, let's apply inline styles to each JSX element.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
const headerStyles = {
backgroundColor: '#61DBFB',
fontFamily: 'Helvetica Neue',
padding: 25,
lineHeight: 1.5,
}
// JSX element, header
const header = (
<header style={headerStyles}>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 2, 2020</small>
</div>
</header>
)
// JSX element, main
const mainStyles = {
backgroundColor: '#F3F0F5',
}
const main = (
<main style={mainStyles}>
<p>Prerequisite to get started react.js:</p>
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
</main>
)
const footerStyles = {
backgroundColor: '#61DBFB',
}
// JSX element, footer
const footer = (
<footer style={footerStyles}>
<p>Copyright 2020</p>
</footer>
)
// JSX element, app
const app = (
<div className='app'>
{header}
{main}
{footer}
</div>
)
const rootElement = document.getElementById('root')
// we render the JSX element using the ReactDOM package
ReactDOM.render(app, rootElement)
```
![Inline styling JSX](../images/styling_jsx_inline_create_react_app.png)
Now, lets apply an internal style, we put all the CSS in the header of the index.html.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// JSX element, header
const header = (
<header>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Instructor: Asabeneh Yetayeh</p>
<small>Date: Oct 1, 2020</small>
</div>
</header>
)
// JSX element, main
const main = (
<main>
<div className='main-wrapper'>
<p>
Prerequisite to get started{' '}
<strong>
<em>react.js</em>
</strong>
:
</p>
<ul>
<li>HTML</li>
<li>CSS</li>
<li> JavaScript</li>
</ul>
</div>
</main>
)
// JSX element, footer
const footer = (
<footer>
<div className='footer-wrapper'>
<p>Copyright 2020</p>
</div>
</footer>
)
// JSX element, app
const app = (
<div className='app'>
{header}
{main}
{footer}
</div>
)
const rootElement = document.getElementById('root')
// we render the JSX element using the ReactDOM package
ReactDOM.render(app, rootElement)
```
![Inline styling JSX](../images/js_internal_style_create_react_app.png)
## Injecting data to JSX elements
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// To get the root element from the HTML document
// JSX element, header
const welcome = 'Welcome to 30 Days Of React'
const title = 'Getting Started React'
const subtitle = 'JavaScript Library'
const author = {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
}
const date = 'Oct 2, 2020'
// JSX element, header
const header = (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
Instructor: {author.firstName} {author.lastName}
</p>
<small>Date: {date}</small>
</div>
</header>
)
const numOne = 3
const numTwo = 2
const result = (
<p>
{numOne} + {numTwo} = {numOne + numTwo}
</p>
)
const yearBorn = 1820
const currentYear = new Date().getFullYear()
const age = currentYear - yearBorn
const personAge = (
<p>
{' '}
{author.firstName} {author.lastName} is {age} years old
</p>
)
// JSX element, main
const techs = ['HTML', 'CSS', 'JavaScript']
const techsFormatted = techs.map((tech) => <li>{tech}</li>)
// JSX element, main
const main = (
<main>
<div className='main-wrapper'>
<p>
Prerequisite to get started{' '}
<strong>
<em>react.js</em>
</strong>
:
</p>
<ul>{techsFormatted}</ul>
{result}
{personAge}
</div>
</main>
)
const copyRight = 'Copyright 2020'
// JSX element, footer
const footer = (
<footer>
<div className='footer-wrapper'>
<p>{copyRight}</p>
</div>
</footer>
)
// JSX element, app
const app = (
<div className='app'>
{header}
{main}
{footer}
</div>
)
const rootElement = document.getElementById('root')
// we render the JSX element using the ReactDOM package
ReactDOM.render(app, rootElement)
```
![Inline styling JSX](../images/inecting_data_to_jsx_create_react_app.png)
## Importing Media Objects in React
How do we import images, video and audio in React? Let's see how we import images first.
Create images folder in the src folder and save an image inside. For instance let's save asabeneh.jpg image and let's import this image to index.js. After importing we will inject it to a JSX expression, user. See the code below.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import asabenehImage from './images/asabeneh.jpg'
const user = (
<div>
<img src={asabenehImage} alt='asabeneh image' />
</div>
)
const rootElement = document.getElementById('root')
// we render the JSX element using the ReactDOM package
ReactDOM.render(user, rootElement)
```
![Rendering image](../images/rendering_image.png)
Let's inject the user inside the main JSX element and see the result:
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// To get the root element from the HTML document
import asabenehImage from './images/asabeneh.jpg'
// JSX element, header
const welcome = 'Welcome to 30 Days Of React'
const title = 'Getting Started React'
const subtitle = 'JavaScript Library'
const author = {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
}
const date = 'Oct 2, 2020'
// JSX element, header
const header = (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
Instructor: {author.firstName} {author.lastName}
</p>
<small>Date: {date}</small>
</div>
</header>
)
const numOne = 3
const numTwo = 2
const result = (
<p>
{numOne} + {numTwo} = {numOne + numTwo}
</p>
)
const yearBorn = 1820
const currentYear = new Date().getFullYear()
const age = currentYear - yearBorn
const personAge = (
<p>
{' '}
{author.firstName} {author.lastName} is {age} years old
</p>
)
// JSX element, main
const techs = ['HTML', 'CSS', 'JavaScript']
const techsFormatted = techs.map((tech) => <li>{tech}</li>)
const user = (
<div>
<img src={asabenehImage} alt='asabeneh image' />
</div>
)
// JSX element, main
const main = (
<main>
<div className='main-wrapper'>
<p>
Prerequisite to get started{' '}
<strong>
<em>react.js</em>
</strong>
:
</p>
<ul>{techsFormatted}</ul>
{result}
{personAge}
{user}
</div>
</main>
)
const copyRight = 'Copyright 2020'
// JSX element, footer
const footer = (
<footer>
<div className='footer-wrapper'>
<p>{copyRight}</p>
</div>
</footer>
)
// JSX element, app
const app = (
<div className='app'>
{header}
{main}
{footer}
</div>
)
const rootElement = document.getElementById('root')
// we render the JSX element using the ReactDOM package
ReactDOM.render(app, rootElement)
```
![All JSX together final](../images/all_jsx_final.png)
The boilerplate code can be found [here](../03/../03_Day_Setting_Up/30-days-of-react_boilerplate)
# Exercises
## Exercises: Level 1
1. What is a module?
2. What is package?
3. What is the difference between a module and a package.
4. What is NPM?
5. What is Webpack?
6. How do you create a new React project?
7. What are the files and folders inside a project folder(package.json, package-lock.json or yarn.lock, .gitignore,node_modules and public)?
8. What is your favorite code editor (I believe that it is Visual Studio Code)?
9. Add different Visual Studio Code extensions to improve your productivity(eg. prettier, ESLint etc).
10. Try to make a different custom module in a different file and import it to index.js.
## Exercises: Level 2
1. Import and render the following images
![Front end](../images/frontend_technologies.png)
2. Use h1, p, input and button HTML elements to create the following design using JSX
![News Letter](../images/news_letter_design.png)
## Exercises: Level 3
1. Design the following user card.
![User Card](../images/user_card_design_jsx.png)
🎉 CONGRATULATIONS ! 🎉
[<< Day 2](../02_Day_Introduction_to_React/02_introduction_to_react.md) | [Day 4 >>](../04_Day_Components/04_components.md)

@ -1,23 +0,0 @@
# 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*

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

@ -1,34 +0,0 @@
{
"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"
]
}
}

@ -1,98 +0,0 @@
<!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: 10px;
}
main {
padding: 10px 10px 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;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

@ -1,116 +0,0 @@
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// To get the root element from the HTML document
import asabenehImage from './images/asabeneh.jpg'
// to import the doSomeMath from the math.js with or without extension
import doSomeMath from './math.js'
// to import the other modules
// since these modules were not exported as default we have to desctructure
import { addTwo, multiply, subtract } from './math.js'
import * as everything from './math.js'
console.log(addTwo(5, 5))
console.log(doSomeMath.addTwo(5, 5))
console.log(everything)
// JSX element, header
// JSX element, header
const welcome = 'Welcome to 30 Days Of React'
const title = 'Getting Started React'
const subtitle = 'JavaScript Library'
const author = {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
}
const date = 'Oct 2, 2020'
// JSX element, header
const header = (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
Instructor: {author.firstName} {author.lastName}
</p>
<small>Date: {date}</small>
</div>
</header>
)
const numOne = 3
const numTwo = 2
const result = (
<p>
{numOne} + {numTwo} = {numOne + numTwo}
</p>
)
const yearBorn = 1820
const currentYear = new Date().getFullYear()
const age = currentYear - yearBorn
const personAge = (
<p>
{' '}
{author.firstName} {author.lastName} is {age} years old
</p>
)
// JSX element, main
const techs = ['HTML', 'CSS', 'JavaScript']
const techsFormatted = techs.map((tech) => <li>{tech}</li>)
const user = (
<div>
<img src={asabenehImage} alt='asabeneh image' />
</div>
)
// JSX element, main
const main = (
<main>
<div className='main-wrapper'>
<p>
Prerequisite to get started{' '}
<strong>
<em>react.js</em>
</strong>
:
</p>
<ul>{techsFormatted}</ul>
{result}
{personAge}
{user}
</div>
</main>
)
const copyRight = 'Copyright 2020'
// JSX element, footer
const footer = (
<footer>
<div className='footer-wrapper'>
<p>{copyRight}</p>
</div>
</footer>
)
// JSX element, app
const app = (
<div className='app'>
{header}
{main}
{footer}
</div>
)
const rootElement = document.getElementById('root')
// we render the JSX element using the ReactDOM package
ReactDOM.render(app, rootElement)

@ -1,12 +0,0 @@
// math.js
export const addTwo = (a, b) => a + b
export const multiply = (a, b) => a * b
export const subtract = (a, b) => a - b
export default(function doSomeMath() {
return {
addTwo,
multiply,
subtract,
}
})()

File diff suppressed because it is too large Load Diff

@ -1,520 +0,0 @@
<div align="center">
<h1> 30 Days Of React: Components </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 3](../30-Days-Of-React/03_Day_Setting_Up/03_setting_up.md) | [Day 5 >>](../05_Day_Props/05_props.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_4.jpg)
- [Components](#components)
- [Big picture of components](#big-picture-of-components)
- [JavaScript function](#javascript-function)
- [JavaScript Class](#javascript-class)
- [Creating React Component](#creating-react-component)
- [Functional Component](#functional-component)
- [Rendering components](#rendering-components)
- [Injecting data to JSX in React Component](#injecting-data-to-jsx-in-react-component)
- [Further on Functional components](#further-on-functional-components)
- [Exercises: Components](#exercises-components)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# Components
A React component is a small, reusable code, which is responsible for one part of the application UI. A React application is an aggregation of components. React can help us to build reusable components. The following diagram shows different components. All the components have different border colors. In React we assemble different components together to create an application. We use JavaScript functions or classes to make components. If we use a function, the component will be a functional component, but if we use a class, the component will be a class-based component.
Components can be:
- Functional Component / Presentational Component / Stateless Component / Dumb Component
- Class Component / Container Component/ Statefull Component / Smart Component
The classification of components above does not work for the latest version of React, but it is good to know the former definition and how the previous versions work.
So, let us change all the JSX to components. Components in React are JavaScript functions or classes, that return a JSX. Component name must start with an uppercase, and if the name is two words, it should be CamelCase - a camel with two humps.
## Big picture of components
In the previous section we agreed, that a website or an application is made of buttons, forms, texts, media objects, header, section, article and footer. If we have a million-dollar button, we can use this button all the time, instead of recreating it all over again, whenever we need a button. The same goes for input fields, forms, header or footer. That is where the power of the component comes. In the following diagram, the header, main and footer are components. Inside the main there is also a user card component and a text section component. All the different colors represent different components. How many colors do you see? Each color represent a single component. We have five components in this diagram.
![Components](../images/components_example.png)
Before we jump into React components, let's do some functions and class refreshers.
## JavaScript function
A JavaScript function could be either a regular function or an arrow function. These functions are not exactly the same there is a slight difference between them.
```js
const getUserInfo = (firstName, lastName, country, title, skills) => {
return `${firstName} ${lastName}, a ${title} developer based in ${country}. He knows ${skills.join(
' '
)} `
}
// When we call this function we need parameters
const skills = ['HTML', 'CSS', 'JS', 'React']
console.log(
getUserInfo('Asabeneh', 'Yetayeh', 'Finland', 'FullStack Developer', skills)
)
```
## JavaScript Class
A class is a blueprint of an object. We instantiate a class to create different objects. In addition, we can create children, by inheriting all the methods and properties of the parent.
```js
class Parent {
constructor(firstName, lastName, country, title) {
// we bind the params with this class object using this keyword
this.firstName = firstName
this.lastName = lastName
this.country = country
this.title = title
}
getPersonInfo() {
return `${this.firstName} ${this.lastName}, a ${this.title} developer base in ${this.country} `
}
parentMethod() {
// code goes here
}
}
const p1 = new Parent('Asabeneh', 'Yetayeh', 'Finland', 'FullStack Developer')
class Child extends Parent {
constructor(firstName, lastName, country, title, skills) {
super(firstName, lastName, country, title)
this.skills = skills
// we bind the child params with the this keyword to this child object
}
getSkills() {
let len = this.skills.length
return len > 0 ? this.skills.join(' ') : 'No skills found'
}
childMethod() {
// code goes here
}
}
const skills = ['HTML', 'CSS', 'JS', 'React']
const child = new Child(
'Asabeneh',
'Yetayeh',
'Finland',
'FullStack Developer',
skills
)
```
We just briefly covered function and class. React component is made of JavaScript functions or classes, so let's make a React component now.
## Creating React Component
### Functional Component
Using a JavaScript function, we can make a functional React component.
```js
// React component syntax
// it can be arrow function, function declaration or function expression
const jsx = <tag> Content </tag>
const ComponentName = () => {
return jsx
}
```
The following expression is a JSX element.
```js
// JSX element, header
const header = (
<header style={headerStyles}>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 3, 2020</small>
</div>
</header>
)
// React Component
const Header = () => {
return header
}
// or we can just return the JSX
const Header = () => {
return (
<header style={headerStyles}>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 3, 2020</small>
</div>
</header>
)
}
// Even th above code can be written like this
// Explicitly returning the JSX
const Header = () => (
<header style={headerStyles}>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 3, 2020</small>
</div>
</header>
)
```
### Rendering components
Now, lets change all the JSX elements we had to components. When we call JSX element we use curly brackets and when we call components we do as follows <ComponentName />. If we pass an attribute, when we call the component name, we call it props(<ComponentName propsName = {'data-type'} />). We will talk about props in another section.[Live on code pen](https://codepen.io/Asabeneh/full/wvaKKEM)
Let's render first the _Header_ component.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// Header Component
const Header = () => (
<header>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 3, 2020</small>
</div>
</header>
)
const rootElement = document.getElementById('root')
// we render the JSX element using the ReactDOM package
ReactDOM.render(<Header />, rootElement)
```
Now, let's create an App component , that will wrap the Header, Main and Footer. Then the App component will be render on the DOM.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import asabenehImage from './images/asabeneh.jpg'
// Header Component
const Header = () => (
<header>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 3, 2020</small>
</div>
</header>
)
// User Card Component
const UserCard = () => (
<div className='user-card'>
<img src={asabenehImage} alt='asabeneh image' />
<h2>Asabeneh Yetayeh</h2>
</div>
)
// TechList Component
const TechList = () => {
const techs = ['HTML', 'CSS', 'JavaScript']
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
// Main Component
const Main = () => (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList />
</ul>
<UserCard />
</div>
</main>
)
// Footer Component
const Footer = () => (
<footer>
<div className='footer-wrapper'>
<p>Copyright 2020</p>
</div>
</footer>
)
// The App, or the parent or the container component
const App = () => (
<div className='app'>
<Header />
<Main />
<Footer />
</div>
)
const rootElement = document.getElementById('root')
// we render the App component using the ReactDOM package
ReactDOM.render(<App />, rootElement)
```
![Rendering Components](../images/rendering_componnets.png)
### Injecting data to JSX in React Component
So far, we used static data on the JSX elements. Now let's pass different data types as dynamic data. The dynamic data could be strings, numbers, booleans, arrays or objects. Let us see each of the data types step by step. To inject data to a JSX we use the {} bracket.
In this section we inject only strings
```js
import React from 'react'
import ReactDOM from 'react-dom'
const welcome = 'Welcome to 30 Days Of React'
const title = 'Getting Started React'
const subtitle = 'JavaScript Library'
const firstName = 'Asabeneh'
const lastName = 'Yetayeh'
const date = 'Oct 3, 2020'
// JSX element, header
const header = () => {
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
Instructor: {firstName} {lastName}
</p>
<small>Date: {date}</small>
</div>
</header>
)
}
const rootElement = document.getElementById('root')
// we render the App component using the ReactDOM package
ReactDOM.render(<Header />, rootElement)
```
Similar to the Header component we can implement to Main and Footer component.
```js
// To get the root element from the HTML document
const rootElement = document.querySelector('.root')
// JSX element, header
const welcome = 'Welcome to 30 Days Of React Challenge'
const title = 'Getting Started React'
const subtitle = 'JavaScript Library'
const author = {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
}
const date = 'Oct 2, 2020'
// JSX element, header
const Header = () => (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
Instructor: {author.firstName} {author.lastName}
</p>
<small>Date: {date}</small>
</div>
</header>
)
const numOne = 3
const numTwo = 2
const result = (
<p>
{numOne} + {numTwo} = {numOne + numTwo}
</p>
)
const yearBorn = 1820
const currentYear = 2020
const age = currentYear - yearBorn
const personAge = (
<p>
{' '}
{author.firstName} {author.lastName} is {age} years old
</p>
)
// User Card Component
const UserCard = () => (
<div className='user-card'>
<img src={asabenehImage} alt='asabeneh image' />
<h2>
{author.firstName} {author.lastName}
</h2>
</div>
)
// JSX element, main
const techs = ['HTML', 'CSS', 'JavaScript']
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
// JSX element, main
const Main = () => (
<main>
<div className='main-wrapper'>
<div>
<p>
Prerequisite to get started{' '}
<strong>
<em>react.js</em>
</strong>
:
</p>
<ul>{techsFormatted}</ul>
{result}
{personAge}
</div>
<UserCard />
</div>
</main>
)
const copyRight = '2020'
// JSX element, footer
const Footer = () => (
<footer>
<div className='footer-wrapper'>
<p>Copyright &copy;{copyRight}</p>
</div>
</footer>
)
// JSX element, app
const app = () => (
<div className='app'>
<Header />
<Main />
<Footer />
</div>
)
// we render the App component using the ReactDOM package
ReactDOM.render(<App />, rootElement)
```
### Further on Functional components
We have transformed all the JSX elements of Day 2 to functional components, and by now you are very familiar with components. Let's create more components. What is the smallest size of a component? A component that returns only a single HTML as JSX is considered as a small component. A button component or an alert box component, or just an input field component.
```js
const Button = () => <button>action</button>
```
The _Button_ component is made of a single HTML button element.
Let's style this button using JavaScript style object. All CSS properties should be camelCase to make a JavaScript CSS object. If we pass a number without unit as CSS value, it is considered as px. See the example below.
```js
const buttonStyles = {
padding: '10px 20px',
background: 'rgb(0, 255, 0',
border: 'none',
borderRadius: 5,
}
const Button = () => <button style={buttonStyles}> action </button>
```
The Button component is a dumb component, because it does not take any parameters and we cannot change the action text dynamically. We need to pass props to the button, to change the value dynamically. We will see props in the next section. Before we close today's lesson let's make another, more functional component, which displays a random hexadecimal number.
```js
import React from 'react'
import ReactDOM from 'react-dom'
// Hexadecimal color generator
const hexaColor = () => {
let str = '0123456789abcdef'
let color = ''
for (let i = 0; i < 6; i++) {
let index = Math.floor(Math.random() * str.length)
color += str[index]
}
return '#' + color
}
const HexaColor = () => <div>{hexaColor()}</div>
const rootElement = document.getElementById('root')
// we render the App component using the ReactDOM package
ReactDOM.render(<HexaColor />, rootElement)
```
# Exercises: Components
## Exercises: Level 1
1. What is the difference between a regular function and an arrow function?
2. What is a React Component?
3. How do you make a React functional component?
4. What is the difference between a pure JavaScript function and a functional component?
5. How small is a React component?
6. Can we make a button or input field component?
7. Make a reusable Button component.
8. Make a reusable InputField component.
9. Make a reusable alert box component with one div parent element and one p child element of the div(warning alert box, success alert box).
## Exercises: Level 2
1. Create functional components and display the following images
![Front end](../images/frontend_technologies.png)
2. Use functional component to create the following design
![News Letter](../images/news_letter_design.png)
## Exercises: Level 3
1. Use the given hexadecimal color generator in the example to create these random colors
![Hexadecimal colors](../images/hexadecimal_color_exercise.png)
2. Use functional component to design the following user card.
![User Card](../images/user_card_design_jsx.png)
🎉 CONGRATULATIONS ! 🎉
[<< Day 3](../30-Days-Of-React/03_Day_Setting_Up/03_setting_up.md) | [Day 5 >>](../05_Day_Props/05_props.md)

@ -1,23 +0,0 @@
# 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*

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

@ -1,34 +0,0 @@
{
"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"
]
}
}

@ -1,111 +0,0 @@
<!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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

@ -1,110 +0,0 @@
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import asabenehImage from './images/asabeneh.jpg'
const hexaColor = () => {
let str = '0123456789abcdef'
let color = ''
for (let i = 0; i < 6; i++) {
let index = Math.floor(Math.random() * str.length)
color += str[index]
}
return '#' + color
}
const HexaColor = () => {
const bgColor = hexaColor()
const styles = {
height: '100px',
display: 'flex',
'justify-content': 'center',
'align-items': 'center',
fontFamily: 'Montserrat',
margin: '2px auto',
borderRadius: '5px',
width: '75%',
border: '2px solid black',
}
return (
<div style={styles}>
<h2>{bgColor}</h2>
</div>
)
}
// Header Component
const Header = () => (
<header>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 3, 2020</small>
</div>
</header>
)
// User Card Component
const UserCard = () => (
<div className='user-card'>
<img src={asabenehImage} alt='asabeneh image' />
<h2>Asabeneh Yetayeh</h2>
</div>
)
// TechList Component
const TechList = () => {
const techs = ['HTML', 'CSS', 'JavaScript']
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
const buttonStyles = {
padding: '10px 20px',
background: 'rgb(0, 255, 0)',
border: 'none',
borderRadius: 5,
}
const Button = () => <button style={buttonStyles}> action </button>
// Main Component
const Main = () => (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList />
</ul>
<UserCard />
<div>
{/* Generate two different hexa colors every time */}
<HexaColor />
<HexaColor />
</div>
</div>
</main>
)
// Footer Component
const Footer = () => (
<footer>
<div className='footer-wrapper'>
<p>Copyright 2020</p>
</div>
</footer>
)
// The App, or the parent or the container component
const App = () => (
<div className='app'>
<Header />
<Main />
<Footer />
</div>
)
const rootElement = document.getElementById('root')
// we render the App component using the ReactDOM package
ReactDOM.render(<App />, rootElement)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,23 +0,0 @@
# 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*

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

@ -1,34 +0,0 @@
{
"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"
]
}
}

@ -1,111 +0,0 @@
<!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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

@ -1,153 +0,0 @@
import React from 'react'
import ReactDOM from 'react-dom'
import asabenehImage from './images/asabeneh.jpg'
// Fuction to show month date year
const showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return ` ${month} ${date}, ${year}`
}
// Header Component
const Header = ({
data: {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
},
}) => {
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{showDate(date)}</small>
</div>
</header>
)
}
// TechList Component
const TechList = ({ techs }) => {
const techList = techs.map((tech) => <li key={tech}>{tech}</li>)
return techList
}
// User Card Component
const UserCard = ({ user: { firstName, lastName, image } }) => (
<div className='user-card'>
<img src={image} alt={firstName} />
<h2>
{firstName}
{lastName}
</h2>
</div>
)
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: 3,
cursor: 'pointer',
fontSize: 18,
color: 'white',
}
// Main Component
const Main = ({ user, techs, greetPeople, handleTime }) => (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList techs={techs} />
</ul>
<UserCard user={user} />
<Button text='Greet People' onClick={greetPeople} style={buttonStyles} />
<Button text='Show Time' onClick={handleTime} style={buttonStyles} />
</div>
</main>
)
// Footer Component
const Footer = ({ copyRight }) => (
<footer>
<div className='footer-wrapper'>
<p>Copyright {copyRight.getFullYear()}</p>
</div>
</footer>
)
// The App, or the parent or the container component
// Functional Component
const App = () => {
const data = {
welcome: 'Welcome to 30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: new Date(), // date needs to be formatted to a human readable format
}
const date = new Date()
const techs = ['HTML', 'CSS', 'JavaScript']
// copying the author from data object to user variable using spread operator
const user = { ...data.author, image: asabenehImage }
const handleTime = () => {
alert(showDate(new Date()))
}
const greetPeople = () => {
alert('Welcome to 30 Days Of React Challenge, 2020')
}
return (
<div className='app'>
<Header data={data} />
<Main
user={user}
techs={techs}
handleTime={handleTime}
greetPeople={greetPeople}
/>
<Footer copyRight={date} />
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

File diff suppressed because it is too large Load Diff

@ -1,288 +0,0 @@
<div align="center">
<h1> 30 Days Of React: Mapping Arrays </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 5](./../05_Day_Props/05_props.md) | [Day 7 >>](../07_Day_Class_Components/07_class_components.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_6.jpg)
- [Mapping arrays](#mapping-arrays)
- [Mapping and rendering arrays](#mapping-and-rendering-arrays)
- [Mapping array of numbers](#mapping-array-of-numbers)
- [Mapping array of arrays](#mapping-array-of-arrays)
- [Mapping array of objects](#mapping-array-of-objects)
- [Key in mapping arrays](#key-in-mapping-arrays)
- [Exercises](#exercises)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# Mapping arrays
An array is the most frequently used data structure to handle many kinds of problems. In React, we use map to modify an array to list of JSX by adding a certain HTML elements to each element of an array.
## Mapping and rendering arrays
Most of the time data is in the form of an array or an array of objects. To render this array or array of objects most of the time we modify the data using _map_. In the previous section, we have rendered the techs list using a map method. In this section, we will see more examples.
In the following examples, you will see how we render an array of numbers, an array of strings, an array of countries and an array of skills on the browser.
```js
import React from 'react'
import ReactDOM from 'react-dom'
const App = () => {
return (
<div className='container'>
<div>
<h1>Numbers List</h1>
{[1, 2, 3, 4, 5]}
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
If you check the browser, you will see the numbers are attached together in one line. To avoid this, we modify the array and change the array elements to JSX element. See the example below, the array has been modified to a list of JSX elements.
### Mapping array of numbers
```js
import React from 'react'
import ReactDOM from 'react-dom'
const Numbers = ({ numbers }) => {
// modifying array to array of li JSX
const list = numbers.map((number) => <li>{number}</li>)
return list
}
// App component
const App = () => {
const numbers = [1, 2, 3, 4, 5]
return (
<div className='container'>
<div>
<h1>Numbers List</h1>
<ul>
<Numbers numbers={numbers} />
</ul>
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
### Mapping array of arrays
Let's see how to map array of arrays
```js
import React from 'react'
import ReactDOM from 'react-dom'
const skills = [
['HTML', 10],
['CSS', 7],
['JavaScript', 9],
['React', 8],
]
// Skill Component
const Skill = ({ skill: [tech, level] }) => (
<li>
{tech} {level}
</li>
)
// Skills Component
const Skills = ({ skills }) => {
const skillsList = skills.map((skill) => <Skill skill={skill} />)
console.log(skillsList)
return <ul>{skillsList}</ul>
}
const App = () => {
return (
<div className='container'>
<div>
<h1>Skills Level</h1>
<Skills skills={skills} />
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
### Mapping array of objects
Rendering array of objects
```js
import React from 'react'
import ReactDOM from 'react-dom'
const countries = [
{ name: 'Finland', city: 'Helsinki' },
{ name: 'Sweden', city: 'Stockholm' },
{ name: 'Denmark', city: 'Copenhagen' },
{ name: 'Norway', city: 'Oslo' },
{ name: 'Iceland', city: 'Reykjavík' },
]
// Country component
const Country = ({ country: { name, city } }) => {
return (
<div>
<h1>{name}</h1>
<small>{city}</small>
</div>
)
}
// countries component
const Countries = ({ countries }) => {
const countryList = countries.map((country) => <Country country={country} />)
return <div>{countryList}</div>
}
// App component
const App = () => (
<div className='container'>
<div>
<h1>Countries List</h1>
<Countries countries={countries} />
</div>
</div>
)
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
### Key in mapping arrays
Keys help React to identify items which have changed, added, or removed. Keys should be given to the elements inside the array to give the elements a stable identity. The key should be unique. Mostly data will come with as an id and we can use id as key. If we do not pass key to React during mapping it raises a warning on the browser. If the data does not have an id we have to find a way to create a unique identifier for each element when we map it. See the following example:
```js
import React from 'react'
import ReactDOM from 'react-dom'
const Numbers = ({ numbers }) => {
// modifying array to array of li JSX
const list = numbers.map((num) => <li key={num}>{num}</li>)
return list
}
const App = () => {
const numbers = [1, 2, 3, 4, 5]
return (
<div className='container'>
<div>
<h1>Numbers List</h1>
<ul>
<Numbers numbers={numbers} />
</ul>
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
Let's also add in key in countries mapping example.
```js
import React from 'react'
import ReactDOM from 'react-dom'
const countries = [
{ name: 'Finland', city: 'Helsinki' },
{ name: 'Sweden', city: 'Stockholm' },
{ name: 'Denmark', city: 'Copenhagen' },
{ name: 'Norway', city: 'Oslo' },
{ name: 'Iceland', city: 'Reykjavík' },
]
// Country component
const Country = ({ country: { name, city } }) => {
return (
<div>
<h1>{name}</h1>
<small>{city}</small>
</div>
)
}
// countries component
const Countries = ({ countries }) => {
const countryList = countries.map((country) => (
<Country key={country.name} country={country} />
))
return <div>{countryList}</div>
}
const App = () => (
<div className='container'>
<div>
<h1>Countries List</h1>
<Countries countries={countries} />
</div>
</div>
)
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
# Exercises
## Exercises: Level 1
1. Why you need to map an array ?
2. Why we need keys during mapping an array ?
3. What is the importance of destructuring your code ?
4. Does destructuring make your code clean and easy to read ?
## Exercises: Level 2
1. In the following design, evens are green, odds are yellow and prime numbers are red. Build the following colors using React component
![Number Generator](../images/day_6_number_generater_exercise.png)
2. Create the following hexadecimal colors using React component
![Number Generator](../images/day_6_hexadecimal_colors_exercise.png)
## Exercises: Level 3
1.Make the following bar group using the given [data](../06_Day_Map_List_Keys/06_map_list_keys_boilerplate/src/data/ten_most_highest_populations.js)
![Ten most highest populations](../images/day_6_ten_highest_populations_exercise.png)
🎉 CONGRATULATIONS ! 🎉
[<< Day 5](./../05_Day_Props/05_props.md) | [Day 7 >>](../07_Day_Class_Components/07_class_components.md)

@ -1,23 +0,0 @@
# 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*

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

@ -1,34 +0,0 @@
{
"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"
]
}
}

@ -1,111 +0,0 @@
<!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>

@ -1,13 +0,0 @@
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.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

@ -1,49 +0,0 @@
import React from 'react'
import ReactDOM from 'react-dom'
// importing data
import { countriesData } from './data/countries'
import { tenMostHighestPopulations } from './data/ten_most_highest_populations'
const countries = [
{ name: 'Finland', city: 'Helsinki' },
{ name: 'Sweden', city: 'Stockholm' },
{ name: 'Denmark', city: 'Copenhagen' },
{ name: 'Norway', city: 'Oslo' },
{ name: 'Iceland', city: 'Reykjavík' },
]
// Country component
const Country = ({ country: { name, city } }) => {
return (
<div>
<h1>{name}</h1>
<small>{city}</small>
</div>
)
}
// countries component
const Countries = ({ countries }) => {
const countryList = countries.map((country) => (
<Country key={country.name} country={country} />
))
return <div>{countryList}</div>
}
// The App, or the parent or the container component
// Functional Component
const App = () => {
return (
<div className='app'>
<div>
<h1>Countries List</h1>
<Countries countries={countries} />
</div>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

File diff suppressed because it is too large Load Diff

@ -1,23 +0,0 @@
# 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*

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

@ -1,34 +0,0 @@
{
"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"
]
}
}

@ -1,111 +0,0 @@
<!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>

@ -1,13 +0,0 @@
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.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

@ -1,194 +0,0 @@
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import asabenehImage from './images/asabeneh.jpg'
// Fuction to show month date year
// User Card Component
const UserCard = ({ user: { firstName, lastName, image } }) => (
<div className='user-card'>
<img src={image} alt={firstName} />
<h2>
{firstName}
{lastName}
</h2>
</div>
)
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: 3,
cursor: 'pointer',
fontSize: 18,
color: 'white',
}
// class based component
class Header extends React.Component {
constructor(props) {
super(props)
// the code inside the constructor run before any other code
}
render() {
console.log(this.props.data)
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
// TechList Component
// class base component
class TechList extends React.Component {
constructor(props) {
super(props)
}
render() {
const { techs } = this.props
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
}
// Main Component
// Class Component
class Main extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList techs={this.props.techs} />
</ul>
<UserCard user={this.props.user} />
<Button
text='Greet People'
onClick={this.props.greetPeople}
style={buttonStyles}
/>
<Button
text='Show Time'
onClick={this.props.handleTime}
style={buttonStyles}
/>
</div>
</main>
)
}
}
// Footer Component
// Class component
class Footer extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<footer>
<div className='footer-wrapper'>
<p>Copyright {this.props.date.getFullYear()}</p>
</div>
</footer>
)
}
}
class App extends React.Component {
showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return ` ${month} ${date}, ${year}`
}
handleTime = () => {
alert(this.showDate(new Date()))
}
greetPeople = () => {
alert('Welcome to 30 Days Of React Challenge, 2020')
}
render() {
const data = {
welcome: 'Welcome to 30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 7, 2020',
}
const techs = ['HTML', 'CSS', 'JavaScript']
// copying the author from data object to user variable using spread operator
const user = { ...data.author, image: asabenehImage }
return (
<div className='app'>
<Header data={data} />
<Main
user={user}
techs={techs}
handleTime={this.handleTime}
greetPeople={this.greetPeople}
/>
<Footer date={new Date()} />
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

@ -1,845 +0,0 @@
<div align="center">
<h1> 30 Days Of React: Class Components </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 6](../06_Day_Map_List_Keys/06_map_list_keys.md) | [Day 8 >>](../08_Day_States/08_states.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_7.jpg)
- [Class Components](#class-components)
- [Accessing props in Class components](#accessing-props-in-class-components)
- [Methods in Class based component](#methods-in-class-based-component)
- [Exercises](#exercises)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# Class Components
In the previous sections, we have covered JSX, functional component and props. In this section, we will cover class components or stateful component. Only class based components used to have state and life cycle methods. However, after React version 16.8.0 functional components can have state and life cycle using React Hooks. In 30 Days Of React challenge, we will cover React before 16.8.0 and after, that mean both old and newest version. There are lots of codes written in older version and at some point it may need migration. In addition, to understand React very well someone has to understand class based component too.
All the previous components are functional components. Let us make also class based component. Class based component is made using JavaScript class and it inherits from react Component. Let us learn how to make a class based component by converting all the functional components we made previously. It is not important to convert all but we are converting them for the sake of learning how to change functional components to class components.
```js
// Pure JavaScript class and child
// Imagine this what we import from React package
class Component {
constructor(props) {}
}
// This how we make class based components by inheriting from the parent
class Child extends Component {
constructor(props) {
super(props)
}
}
```
Functional React component
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// Header Component
// Functional component
const Header = () => (
<header>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 6, 2020</small>
</div>
</header>
)
const rootElement = document.getElementById('root')
ReactDOM.render(<Header />, rootElement)
```
Class based React component is a child of React.Component and it has a built-in render method and it may have a constructor.
```js
//index.js
import React from 'react'
import ReactDOM from 'react-dom'
// class based component
class Header extends React.Component {
render() {
return (
<header>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 7, 2020</small>
</div>
</header>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<Header />, rootElement)
```
Let's see the above component with a constructor
```js
//index.js
import React from 'react'
import ReactDOM from 'react-dom'
// class base component
class Header extends React.Component {
constructor(props) {
super(props)
// the code inside the constructor run before any other code
}
render() {
return (
<header>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 7, 2020</small>
</div>
</header>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<Header />, rootElement)
```
Let's change all the functional component to class based components
```js
// TechList Component
// functional component
const TechList = () => {
const techs = ['HTML', 'CSS', 'JavaScript']
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
// TechList Component
// class base component
class TechList extends React.Component {
constructor(props) {
super(props)
}
render() {
const techs = ['HTML', 'CSS', 'JavaScript']
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
}
// Main Component
// Functional Component
const Main = () => (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList />
</ul>
</div>
</main>
)
// Main Component
// Class Component
class Main extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList />
</ul>
</div>
</main>
)
}
}
// Footer Component
// Functional component
const Footer = () => (
<footer>
<div className='footer-wrapper'>
<p>Copyright 2020</p>
</div>
</footer>
)
// Footer Component
// Class component
class Footer extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<footer>
<div className='footer-wrapper'>
<p>Copyright 2020</p>
</div>
</footer>
)
}
}
// The App, or the parent or the container component
// Functional Component
const App = () => (
<div className='app'>
<Header />
<Main />
<Footer />
</div>
)
// The App, or the parent or the container component
// Class Component
class App extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<div className='app'>
<Header />
<Main />
<Footer />
</div>
)
}
}
```
Let's put all the class based components together in one file.
```js
//index.js
import React from 'react'
import ReactDOM from 'react-dom'
// class base component
class Header extends React.Component {
constructor(props) {
super(props)
// the code inside the constructor run before any other code
}
render() {
return (
<header>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 7, 2020</small>
</div>
</header>
)
}
}
// TechList Component
// class base component
class TechList extends React.Component {
constructor(props) {
super(props)
}
render() {
const techs = ['HTML', 'CSS', 'JavaScript']
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
}
// Main Component
// Class Component
class Main extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList />
</ul>
</div>
</main>
)
}
}
// Footer Component
// Class component
class Footer extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<footer>
<div className='footer-wrapper'>
<p>Copyright 2020</p>
</div>
</footer>
)
}
}
// The App, or the parent or the container component
// Class Component
class App extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<div className='app'>
<Header />
<Main />
<Footer />
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
## Accessing props in Class components
We stated that props is a means to send data from on component to another or we can call it that props is a data carrier. Therefore, we should handle props in class based component too. We can access props of a class based component using the keyword _this_. See the example below.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// class based component
class Header extends React.Component {
constructor(props) {
super(props)
// the code inside the constructor run before any other code
}
render() {
return (
<header>
<div className='header-wrapper'>
<h1>{this.props.data.welcome}</h1>
<h2>{this.props.data.title}</h2>
<h3>
{this.props.data.author.firstName} {this.props.data.author.lastName}
</h3>
<small>{this.props.data.date}</small>
</div>
</header>
)
}
}
const App = () => {
const data = {
welcome: 'Welcome to 30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 7, 2020',
}
return (
<div className='app'>
<Header data={data} />
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
As you can see in the above example, to get the data out from props we have write _props.data_ every time. We can avoid this repetition using destructuring.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// class based component
class Header extends React.Component {
constructor(props) {
super(props)
// the code inside the constructor run before any other code
}
render() {
console.log(this.props.data)
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
const App = () => {
const data = {
welcome: 'Welcome to 30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 6, 2020',
}
return (
<div className='app'>
<Header data={data} />
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
As you can see, the above code cleaner than the previous. Now, let's clean all the components we have and put all together.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// class based component
class Header extends React.Component {
constructor(props) {
super(props)
// the code inside the constructor run before any other code
}
render() {
console.log(this.props.data)
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
// TechList Component
// class base component
class TechList extends React.Component {
constructor(props) {
super(props)
}
render() {
const { techs } = this.props
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
}
// Main Component
// Class Component
class Main extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList techs={this.props.techs} />
</ul>
</div>
</main>
)
}
}
// Footer Component
// Class component
class Footer extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<footer>
<div className='footer-wrapper'>
<p>Copyright {this.props.date.getFullYear()}</p>
</div>
</footer>
)
}
}
class App extends React.Component {
render() {
const data = {
welcome: 'Welcome to 30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 7, 2020',
}
const techs = ['HTML', 'CSS', 'JavaScript']
return (
<div className='app'>
<Header data={data} />
<Main techs={techs} />
<Footer date={new Date()} />
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
## Methods in Class based component
We access methods in class based component. Most of the time, we write different methods on the parent component and we pass them to child components. Let's see the implementation.
Let's add a method on this component.
```js
//index.js
import React from 'react'
import ReactDOM from 'react-dom'
// class based component
class Header extends React.Component {
greetPeople = () => {
alert('Welcome to 30 Days Of React Challenge, 2020')
}
render() {
return (
<header>
<div className='header-wrapper'>
<h1>Welcome to 30 Days Of React</h1>
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3>
<p>Asabeneh Yetayeh</p>
<small>Oct 7, 2020</small>
<button onClick={this.greetPeople}> Greet </button>
</div>
</header>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<Header />, rootElement)
```
The invoking or calling of the method triggers when the event occurs. Therefore, whenever you pass a method to an event listener do not invoke the method.
Now, let's the code we had add all the necessary methods.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import asabenehImage from './images/asabeneh.jpg'
// Fuction to show month date year
// User Card Component
const UserCard = ({ user: { firstName, lastName, image } }) => (
<div className='user-card'>
<img src={image} alt={firstName} />
<h2>
{firstName}
{lastName}
</h2>
</div>
)
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: 3,
cursor: 'pointer',
fontSize: 18,
color: 'white',
}
// class based component
class Header extends React.Component {
constructor(props) {
super(props)
// the code inside the constructor run before any other code
}
render() {
console.log(this.props.data)
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
// TechList Component
// class base component
class TechList extends React.Component {
constructor(props) {
super(props)
}
render() {
const { techs } = this.props
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
}
// Main Component
// Class Component
class Main extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList techs={this.props.techs} />
</ul>
<UserCard user={this.props.user} />
<Button
text='Greet People'
onClick={this.props.greetPeople}
style={buttonStyles}
/>
<Button
text='Show Time'
onClick={this.props.handleTime}
style={buttonStyles}
/>
</div>
</main>
)
}
}
// Footer Component
// Class component
class Footer extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<footer>
<div className='footer-wrapper'>
<p>Copyright {this.props.date.getFullYear()}</p>
</div>
</footer>
)
}
}
class App extends React.Component {
showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return ` ${month} ${date}, ${year}`
}
handleTime = () => {
alert(this.showDate(new Date()))
}
greetPeople = () => {
alert('Welcome to 30 Days Of React Challenge, 2020')
}
render() {
const data = {
welcome: 'Welcome to 30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 7, 2020',
}
const techs = ['HTML', 'CSS', 'JavaScript']
// copying the author from data object to user variable using spread operator
const user = { ...data.author, image: asabenehImage }
return (
<div className='app'>
<Header data={data} />
<Main
user={user}
techs={techs}
handleTime={this.handleTime}
greetPeople={this.greetPeople}
/>
<Footer date={new Date()} />
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
Most of the time the container or the parent component can be written as class component and others as functional or presentational components. Data usually flows from parent components to child component and it is unidirectional. However, the latest version of react can allow us to write every component in our application only with functional components. This was impossible in previous versions.
In next section, we will cover state which is the heart of React. State allows React component to rerender when whenever there is a change in state.
# Exercises
## Exercises: Level 1
1. How do you write a pure JavaScript function
2. What is inheritance and how do you make a child from a parent class?
3. What is class based React component ?
4. What is the difference between functional React component and class based React component ?
5. When do we need to use class based components instead of functional components
6. What is the use cases of class based component ?
7. Which type of component do use most frequently ? functional or class-based component
8. What is React life cycle ? (not covered yet) ?
9. What is state in React ? (not covered yet)
## Exercises: Level 2
Learn more about class based component by changing previous days exercises to class based components
## Exercises: Level 3
Coming ...
🎉 CONGRATULATIONS ! 🎉
[<< Day 6](../06_Day_Map_List_Keys/06_map_list_keys.md) | [Day 8 >>](../08_Day_States/08_states.md)

@ -1,513 +0,0 @@
<div align="center">
<h1> 30 Days Of React: States</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 7](../07_Day_Class_Components/07_class_components.md) | [Day 9 >>](../09_Day_Conditional_Rendering/09_conditional_rendering.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_8.jpg)
- [States](#states)
- [What is State?](#what-is-state)
- [How to set a state](#how-to-set-a-state)
- [Resetting a state using a JavaScript method](#resetting-a-state-using-a-javascript-method)
- [Exercises](#exercises)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# States
## What is State?
What is state ? The English meaning of state is _the particular condition that someone or something is in at a specific time_.
Let us see some states being something - Are you happy or sad? - Is light on or off ? Is present or absent ? - Is full or empty ? For instance, I am happy because I am enjoying creating 30 Days Of React challenge. I believe that you are happy too.
State is an object in react which let the component re-render when state data changes.
## How to set a state
We set an initial state inside the constructor or outside the constructor of a class based component. We do not directly change or mutate the state but we use the _setState()_ method to reset to a new state. . As you can see below in the state object we have count with initial value 0. We can access the state object using _this.state_ and the property name. See the example below.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
// declaring state
state = {
count: 0,
}
render() {
// accessing the state value
const count = this.state.count
return (
<div className='App'>
<h1>{count} </h1>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
If you run the above code you will see zero on the browser. We can increase or decrease the value the state by changing the value of the state using JavaScript method.
## Resetting a state using a JavaScript method
Now, let's add some methods which increase or decrease the value of count by clicking a button. Let us add a button to increase and a button to decrease the value of count. To set the state we use react method _this.setState_. See the example below
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
// declaring state
state = {
count: 0,
}
render() {
// accessing the state value
const count = this.state.count
return (
<div className='App'>
<h1>{count} </h1>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Add One
</button>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
If you understand the above example, adding minus one method will be easy. Let us add the minus one method on the click event.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
// declaring state
state = {
count: 0,
}
render() {
// accessing the state value
const count = this.state.count
return (
<div className='App'>
<h1>{count} </h1>
<div>
<button
onClick={() => this.setState({ count: this.state.count + 1 })}
>
Add One
</button>{' '}
<button
onClick={() => this.setState({ count: this.state.count - 1 })}
>
Minus One
</button>
</div>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
Both button work well, but we need to re-structure the code well. Let us create separate methods in the component.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
// declaring state
state = {
count: 0,
}
// method which add one to the state
addOne = () => {
this.setState({ count: this.state.count + 1 })
}
// method which subtract one to the state
minusOne = () => {
this.setState({ count: this.state.count - 1 })
}
render() {
// accessing the state value
const count = this.state.count
return (
<div className='App'>
<h1>{count} </h1>
<div>
<button className='btn btn-add' onClick={this.addOne}>
+1
</button>{' '}
<button className='btn btn-minus' onClick={this.minusOne}>
-1
</button>
</div>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
Let us do more example about state, in the following example we will develop small application which shows either a dog or cat.
We can start by setting the initial state with cat then when it is clicked it will show dog and alternatively. We need one method which changes the animal alternatively. See the code below. If you want to see live click [here](https://codepen.io/Asabeneh/full/LYVxKpq).
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
class App extends React.Component {
// declaring state
state = {
image: 'https://www.smithsstationah.com/imagebank/eVetSites/Feline/01.jpg',
}
changeAnimal = () => {
let dogURL =
'https://static.onecms.io/wp-content/uploads/sites/12/2015/04/dogs-pembroke-welsh-corgi-400x400.jpg'
let catURL =
'https://www.smithsstationah.com/imagebank/eVetSites/Feline/01.jpg'
let image = this.state.image === catURL ? dogURL : catURL
this.setState({ image })
}
render() {
// accessing the state value
const count = this.state.count
return (
<div className='App'>
<h1>30 Days Of React</h1>
<div className='animal'>
<img src={this.state.image} alt='animal' />
</div>
<button onClick={this.changeAnimal} class='btn btn-add'>
Change
</button>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
Now, let's put all the codes we have so far and also let's implement state when it is necessary.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import asabenehImage from './images/asabeneh.jpg'
// Fuction to show month date year
const showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return ` ${month} ${date}, ${year}`
}
// User Card Component
const UserCard = ({ user: { firstName, lastName, image } }) => (
<div className='user-card'>
<img src={image} alt={firstName} />
<h2>
{firstName}
{lastName}
</h2>
</div>
)
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: 3,
cursor: 'pointer',
fontSize: 18,
color: 'white',
}
// class based component
class Header extends React.Component {
constructor(props) {
super(props)
// the code inside the constructor run before any other code
}
render() {
console.log(this.props.data)
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header style={this.props.styles}>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
const Count = ({ count, addOne, minusOne }) => (
<div>
<h1>{count} </h1>
<div>
<Button text='+1' onClick={addOne} style={buttonStyles} />
<Button text='-1' onClick={minusOne} style={buttonStyles} />
</div>
</div>
)
// TechList Component
// class base component
class TechList extends React.Component {
constructor(props) {
super(props)
}
render() {
const { techs } = this.props
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
}
// Main Component
// Class Component
class Main extends React.Component {
constructor(props) {
super(props)
}
render() {
const {
techs,
user,
greetPeople,
handleTime,
changeBackground,
count,
addOne,
minusOne,
} = this.props
return (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList techs={techs} />
</ul>
<UserCard user={user} />
<Button
text='Greet People'
onClick={greetPeople}
style={buttonStyles}
/>
<Button text='Show Time' onClick={handleTime} style={buttonStyles} />
<Button
text='Change Background'
onClick={changeBackground}
style={buttonStyles}
/>
<Count count={count} addOne={addOne} minusOne={minusOne} />
</div>
</main>
)
}
}
// Footer Component
// Class component
class Footer extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<footer>
<div className='footer-wrapper'>
<p>Copyright {this.props.date.getFullYear()}</p>
</div>
</footer>
)
}
}
class App extends React.Component {
state = {
count: 0,
styles: {
backgroundColor: '',
color: '',
},
}
showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return ` ${month} ${date}, ${year}`
}
addOne = () => {
this.setState({ count: this.state.count + 1 })
}
// method which subtract one to the state
minusOne = () => {
this.setState({ count: this.state.count - 1 })
}
handleTime = () => {
alert(this.showDate(new Date()))
}
greetPeople = () => {
alert('Welcome to 30 Days Of React Challenge, 2020')
}
changeBackground = () => {}
render() {
const data = {
welcome: 'Welcome to 30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 7, 2020',
}
const techs = ['HTML', 'CSS', 'JavaScript']
const date = new Date()
// copying the author from data object to user variable using spread operator
const user = { ...data.author, image: asabenehImage }
return (
<div className='app'>
{this.state.backgroundColor}
<Header data={data} />
<Main
user={user}
techs={techs}
handleTime={this.handleTime}
greetPeople={this.greetPeople}
changeBackground={this.changeBackground}
addOne={this.addOne}
minusOne={this.minusOne}
count={this.state.count}
/>
<Footer date={new Date()} />
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
I believe that now you have a very good understanding of state. After this, we will use state in other sections too because state and props is the core of a react application.
## Exercises
### Exercises: Level 1
1. What was your state today? Are you happy? I hope so. If you manage to make it this far you should be happy.
2. What is state in React ?
3. What is the difference between props and state in React ?
4. How do you access state in a React component ?
5. How do you set a set in a React component ?
### Exercises: Level 2
1. Use React state to change the background of the page. You can use this technique to apply a dark mode for your portfolio.
![Change Background](../images/08_day_changing_background_exercise.gif)
2. After long time of lock down, you may think of travelling and you do not know where to go. You may be interested to develop a random country selector that selects your holiday destination.
![Change Background](../images/08_day_select_country_exercise.gif)
### Exercises: Level 3
Coming
🎉 CONGRATULATIONS ! 🎉
[<< Day 7](../07_Day_Class_Components/07_class_components.md) | [Day 9 >>](../09_Day_Conditional_Rendering/09_conditional_rendering.md)

@ -1,23 +0,0 @@
# 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*

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

@ -1,34 +0,0 @@
{
"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"
]
}
}

@ -1,111 +0,0 @@
<!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

@ -1,13 +0,0 @@
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.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

@ -1,256 +0,0 @@
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import asabenehImage from './images/asabeneh.jpg'
// Fuction to show month date year
const showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return ` ${month} ${date}, ${year}`
}
// User Card Component
const UserCard = ({ user: { firstName, lastName, image } }) => (
<div className='user-card'>
<img src={image} alt={firstName} />
<h2>
{firstName}
{lastName}
</h2>
</div>
)
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: 3,
cursor: 'pointer',
fontSize: 18,
color: 'white',
}
// class based component
class Header extends React.Component {
constructor(props) {
super(props)
// the code inside the constructor run before any other code
}
render() {
console.log(this.props.data)
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header style={this.props.styles}>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
const Count = ({ count, addOne, minusOne }) => (
<div>
<h1>{count} </h1>
<div>
<Button text='+1' onClick={addOne} style={buttonStyles} />
<Button text='-1' onClick={minusOne} style={buttonStyles} />
</div>
</div>
)
// TechList Component
// class base component
class TechList extends React.Component {
constructor(props) {
super(props)
}
render() {
const { techs } = this.props
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
}
// Main Component
// Class Component
class Main extends React.Component {
constructor(props) {
super(props)
}
render() {
const {
techs,
user,
greetPeople,
handleTime,
changeBackground,
count,
addOne,
minusOne,
} = this.props
return (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList techs={techs} />
</ul>
<UserCard user={user} />
<Button
text='Greet People'
onClick={greetPeople}
style={buttonStyles}
/>
<Button text='Show Time' onClick={handleTime} style={buttonStyles} />
<Button
text='Change Background'
onClick={changeBackground}
style={buttonStyles}
/>
<Count count={count} addOne={addOne} minusOne={minusOne} />
</div>
</main>
)
}
}
// Footer Component
// Class component
class Footer extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<footer>
<div className='footer-wrapper'>
<p>Copyright {this.props.date.getFullYear()}</p>
</div>
</footer>
)
}
}
class App extends React.Component {
state = {
count: 0,
styles: {
backgroundColor: '',
color: '',
},
}
showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return ` ${month} ${date}, ${year}`
}
addOne = () => {
this.setState({ count: this.state.count + 1 })
}
// method which subtract one to the state
minusOne = () => {
this.setState({ count: this.state.count - 1 })
}
handleTime = () => {
alert(this.showDate(new Date()))
}
greetPeople = () => {
alert('Welcome to 30 Days Of React Challenge, 2020')
}
changeBackground = () => {}
render() {
const data = {
welcome: 'Welcome to 30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 7, 2020',
}
const techs = ['HTML', 'CSS', 'JavaScript']
const date = new Date()
// copying the author from data object to user variable using spread operator
const user = { ...data.author, image: asabenehImage }
return (
<div className='app'>
{this.state.backgroundColor}
<Header data={data} />
<Main
user={user}
techs={techs}
handleTime={this.handleTime}
greetPeople={this.greetPeople}
changeBackground={this.changeBackground}
addOne={this.addOne}
minusOne={this.minusOne}
count={this.state.count}
/>
<Footer date={new Date()} />
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

File diff suppressed because it is too large Load Diff

@ -1,782 +0,0 @@
<div align="center">
<h1> 30 Days Of React: Conditional Rendering</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 8](../08_Day_States/08_states.md) | [Day 10 >>](../10_React_Project_Folder_Structure/10_react_project_folder_structure.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_9.jpg)
# Conditional Rendering
As we can understand from the term, conditional rendering is a way to render different JSX or component at different condition. We can implement conditional rendering using regular if and else statement, ternary operator and &&. Let's implement a different conditional rendering.
## Conditional Rendering using If and Else statement
In the code below, we have an initial state of loggedIn which is false. If the state is false we inform user to log in otherwise we welcome the user.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// class based component
class Header extends React.Component {
render() {
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
<p>Select a country for your next holiday</p>
</div>
</header>
)
}
}
class App extends React.Component {
state = {
loggedIn: false,
}
render() {
const data = {
welcome: '30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 9, 2020',
}
// conditional rendering using if and else statement
let status
if (this.state.loggedIn) {
status = <h3>Welcome to 30 Days Of React</h3>
} else {
status = <h3>Please Login</h3>
}
return (
<div className='app'>
<Header data={data} />
{status}
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
Let's add a method which allow as to toggle the status of the user. We should have a button to handle event for logging in and logging out.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: '3px auto',
cursor: 'pointer',
fontSize: 22,
color: 'white',
}
// class based component
class Header extends React.Component {
render() {
console.log(this.props.data)
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
class App extends React.Component {
state = {
loggedIn: false,
}
handleLogin = () => {
this.setState({
loggedIn: !this.state.loggedIn,
})
}
render() {
const data = {
welcome: '30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 9, 2020',
}
let status
let text
if (this.state.loggedIn) {
status = <h1>Welcome to 30 Days Of React</h1>
text = 'Logout'
} else {
status = <h3>Please Login</h3>
text = 'Login'
}
return (
<div className='app'>
<Header data={data} />
{status}
<Button text={text} style={buttonStyles} onClick={this.handleLogin} />
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
How about if our condition is more than two? Like pure JavaScript we can use if else if statement. In general, conditional rendering is not different from pure JavaScript conditional statement.
## Conditional Rendering using Ternary Operator
Ternary operator is an an alternative for if else statement. However, there is more use cases for ternary operator than if else statement. For example, use can use ternary operator inside styles, className or many places in a component than regular if else statement.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: '3px auto',
cursor: 'pointer',
fontSize: 22,
color: 'white',
}
// class based component
class Header extends React.Component {
render() {
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
class App extends React.Component {
state = {
loggedIn: false,
}
handleLogin = () => {
this.setState({
loggedIn: !this.state.loggedIn,
})
}
render() {
const data = {
welcome: '30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 9, 2020',
}
let status = this.state.loggedIn ? (
<h1>Welcome to 30 Days Of React</h1>
) : (
<h3>Please Login</h3>
)
return (
<div className='app'>
<Header data={data} />
{status}
<Button
text={this.state.loggedIn ? 'Logout' : 'Login'}
style={buttonStyles}
onClick={this.handleLogin}
/>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
In addition to JSX, we can also conditionally render a component. Let's change the above conditional JSX to a component.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: '3px auto',
cursor: 'pointer',
fontSize: 22,
color: 'white',
}
// class based component
class Header extends React.Component {
render() {
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
const Login = () => (
<div>
<h3>Please Login</h3>
</div>
)
const Welcome = (props) => (
<div>
<h1>Welcome to 30 Days Of React</h1>
</div>
)
class App extends React.Component {
state = {
loggedIn: false,
}
handleLogin = () => {
this.setState({
loggedIn: !this.state.loggedIn,
})
}
render() {
const data = {
welcome: '30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 9, 2020',
}
const status = this.state.loggedIn ? <Welcome /> : <Login />
return (
<div className='app'>
<Header data={data} />
{status}
<Button
text={this.state.loggedIn ? 'Logout' : 'Login'}
style={buttonStyles}
onClick={this.handleLogin}
/>
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
## Conditional Rendering using && Operator
The && operator render the right JSX operand if the left operand(expression) is true.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: '3px auto',
cursor: 'pointer',
fontSize: 22,
color: 'white',
}
// class based component
class Header extends React.Component {
render() {
console.log(this.props.data)
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header style={this.props.styles}>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
const Login = () => (
<div>
<h3>Please Login</h3>
</div>
)
const Welcome = (props) => (
<div>
<h1>Welcome to 30 Days Of React</h1>
</div>
)
class App extends React.Component {
state = {
loggedIn: false,
techs: ['HTML', 'CSS', 'JS'],
}
handleLogin = () => {
this.setState({
loggedIn: !this.state.loggedIn,
})
}
render() {
const data = {
welcome: '30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 9, 2020',
}
// We can destructure state
const { loggedIn, techs } = this.state
const status = loggedIn ? <Welcome /> : <Login />
return (
<div className='app'>
<Header data={data} />
{status}
<Button
text={loggedIn ? 'Logout' : 'Login'}
style={buttonStyles}
onClick={this.handleLogin}
/>
{techs.length === 3 && (
<p>You have all the prerequisite courses to get started React</p>
)}
{!loggedIn && (
<p>
Please login to access more information about 30 Days Of React
challenge
</p>
)}
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
In the previous section, we used alert box to greet people and also to display time. Let's render the greeting and time on browser DOM instead of displaying on alert box.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// class based component
class Header extends React.Component {
render() {
console.log(this.props.data)
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header style={this.props.styles}>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
const Message = ({ message }) => (
<div>
<h1>{message}</h1>
</div>
)
const Login = () => (
<div>
<h3>Please Login</h3>
</div>
)
const Welcome = (props) => (
<div>
<h1>Welcome to 30 Days Of React</h1>
</div>
)
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// TechList Component
// class base component
class TechList extends React.Component {
render() {
const { techs } = this.props
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
}
// Main Component
// Class Component
class Main extends React.Component {
render() {
const {
techs,
greetPeople,
handleTime,
loggedIn,
handleLogin,
message,
} = this.props
console.log(message)
const status = loggedIn ? <Welcome /> : <Login />
return (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList techs={this.props.techs} />
</ul>
{techs.length === 3 && (
<p>You have all the prerequisite courses to get started React</p>
)}
<div>
<Button
text='Show Time'
onClick={handleTime}
style={buttonStyles}
/>{' '}
<Button
text='Greet People'
onClick={greetPeople}
style={buttonStyles}
/>
{!loggedIn && <p>Please login to access more information about 30 Days Of React challenge</p>}
</div>
<div style={{ margin: 30 }}>
<Button
text={loggedIn ? 'Logout' : 'Login'}
style={buttonStyles}
onClick={handleLogin}
/>
<br />
{status}
</div>
<Message message={message} />
</div>
</main>
)
}
}
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: '3px auto',
cursor: 'pointer',
fontSize: 22,
color: 'white',
}
// Footer Component
// Class component
class Footer extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<footer>
<div className='footer-wrapper'>
<p>Copyright {this.props.date.getFullYear()}</p>
</div>
</footer>
)
}
}
class App extends React.Component {
state = {
loggedIn: false,
techs: ['HTML', 'CSS', 'JS'],
message: 'Click show time or Greet people to change me',
}
handleLogin = () => {
this.setState({
loggedIn: !this.state.loggedIn,
})
}
showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return `${month} ${date}, ${year}`
}
handleTime = () => {
let message = this.showDate(new Date())
this.setState({ message })
}
greetPeople = () => {
let message = 'Welcome to 30 Days Of React Challenge, 2020'
this.setState({ message })
}
render() {
const data = {
welcome: '30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 9, 2020',
}
return (
<div className='app'>
<Header data={data} />
<Main
techs={techs}
handleTime={this.handleTime}
greetPeople={this.greetPeople}
loggedIn={this.state.loggedIn}
handleLogin={this.handleLogin}
message={this.state.message}
/>
<Footer date={new Date()} />
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
## Testimony
Now it is time to express your thoughts about the Author and 30DaysOfReact. You can leave your testimonial on this [link](https://testimonify.herokuapp.com/)
## Exercises
### Exercises: Level 1
1. What is conditional rendering?
2. How do you implement conditional rendering?
3. Which method of conditional rendering do you prefer to use?
### Exercises: Level 2
1. Make a single page application which changes the body of the background based on the season of the year(Autumn, Winter, Spring, Summer)
2. Make a single page application which change the body of the background based on the time of the day(Morning, Noon, Evening, Night)
### Exercises: Level 3
1. Fetching data takes some amount of time. A user has to wait until the data get loaded. Implement a loading functionality of a data is not fetched yet. You can simulate the delay using setTimeout.
🎉 CONGRATULATIONS ! 🎉
[<< Day 8](../08_Day_States/08_states.md) | [Day 10 >>](../10_React_Project_Folder_Structure/10_react_project_folder_structure.md)

@ -1,23 +0,0 @@
# 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*

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

@ -1,34 +0,0 @@
{
"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"
]
}
}

@ -1,111 +0,0 @@
<!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>

@ -1,13 +0,0 @@
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.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

@ -1,227 +0,0 @@
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
// class based component
class Header extends React.Component {
render() {
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
const Message = ({ message }) => (
<div>
<h1>{message}</h1>
</div>
)
const Login = () => (
<div>
<h3>Please Login</h3>
</div>
)
const Welcome = (props) => (
<div>
<h1>Welcome to 30 Days Of React</h1>
</div>
)
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// TechList Component
// class base component
class TechList extends React.Component {
render() {
const { techs } = this.props
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
}
// Main Component
// Class Component
class Main extends React.Component {
render() {
const {
techs,
greetPeople,
handleTime,
loggedIn,
handleLogin,
message,
} = this.props
console.log(message)
const status = loggedIn ? <Welcome /> : <Login />
return (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList techs={this.props.techs} />
</ul>
{techs.length === 3 && (
<p>You have all the prerequisite courses to get started React</p>
)}
<div>
<Button
text='Show Time'
onClick={handleTime}
style={buttonStyles}
/>{' '}
<Button
text='Greet People'
onClick={greetPeople}
style={buttonStyles}
/>
{!loggedIn && (
<p>
Please login to access more information about 30 Days Of React
challenge
</p>
)}
</div>
<div style={{ margin: 30 }}>
<Button
text={loggedIn ? 'Logout' : 'Login'}
style={buttonStyles}
onClick={handleLogin}
/>
<br />
{status}
</div>
<Message message={message} />
</div>
</main>
)
}
}
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: '3px auto',
cursor: 'pointer',
fontSize: 22,
color: 'white',
}
// Footer Component
// Class component
class Footer extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<footer>
<div className='footer-wrapper'>
<p>Copyright {this.props.date.getFullYear()}</p>
</div>
</footer>
)
}
}
class App extends React.Component {
state = {
loggedIn: false,
techs: ['HTML', 'CSS', 'JS'],
message: 'Click show time or Greet people to change me',
}
handleLogin = () => {
this.setState({
loggedIn: !this.state.loggedIn,
})
}
showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return `${month} ${date}, ${year}`
}
handleTime = () => {
let message = this.showDate(new Date())
this.setState({ message })
}
greetPeople = () => {
let message = 'Welcome to 30 Days Of React Challenge, 2020'
this.setState({ message })
}
render() {
const data = {
welcome: '30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 9, 2020',
}
const techs = ['HTML', 'CSS', 'JavaScript']
return (
<div className='app'>
<Header data={data} />
<Main
techs={techs}
handleTime={this.handleTime}
greetPeople={this.greetPeople}
loggedIn={this.state.loggedIn}
handleLogin={this.handleLogin}
message={this.state.message}
/>
<Footer date={new Date()} />
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

@ -1,623 +0,0 @@
<div align="center">
<h1> 30 Days Of React: React Project Folder Structure</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 9](../09_Day_Conditional_Rendering/09_conditional_rendering.md) | [Day 11 >>](../11_Day_Events/11_events.md)
![30 Days of React banner](../images/30_days_of_react_banner_day_10.jpg)
- [React Project Folder Structure and File Naming](#react-project-folder-structure-and-file-naming)
- [File Naming](#file-naming)
- [Folder](#folder)
- [Components Folder](#components-folder)
- [Fragments](#fragments)
- [Exercises](#exercises)
- [Exercises:Level 1](#exerciseslevel-1)
- [Exercises:Level 2](#exerciseslevel-2)
- [Exercises: Level 3](#exercises-level-3)
# React Project Folder Structure and File Naming
There is no strict way to use a single folder structure or file naming in React project. Most of the time, these kind of choice can be made by a team. Sometimes a company may have a developed guidelines about what code conventions to follow, folder structure and file naming. There is no right or wrong way of structuring a React project but some structures are better than the others for scalability,maintainability, ease of working on files and easy to understand structure. If you like to learn further about folder structure you may check the following articles.
- [React Folder Structure by https://www.devaradise.com ](https://www.devaradise.com/react-project-folder-structure)
- [React Folder Structure by www.robinwieruch.de ](https://www.robinwieruch.de/react-folder-structure)
- [React Folder Structure by Faraz Ahmad](https://dev.to/farazamiruddin/an-opinionated-guide-to-react-folder-structure-file-naming-1l7i)
- [React Folder Structure by https://maxrozen.com/](https://maxrozen.com/guidelines-improve-react-app-folder-structure/)
I use a mix of different conventions. If you like you can follow it but please stick in a structure which you think makes sense for you.
## File Naming
In all my React project, I will use CamelCase file name for all components. I prefer to use descriptive long name.
## Folder
I found it easy to put all images, icons and fonts in the assets folder and all CSS style sheets in styles folder. All components will be in the components folder.
So far, we have been working on index.js file. We have lots of component on index.js. Today we will move every component to a single file and we will import all the files to App.js. In the process, you will see my folder structure. Currently, we are at src directory. All the folder structure will be inside the src directory. Let's start from the index.js file. In addition to index.js file, let's create an App.js file and move most of the components we had to App.js for the time being.
The index.js is your getaway to connect the component with index.html.
```js
// src/index.js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
const App = () => <h1>Welcome to 30 Days Of React</h1>
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
In the above snippet of code, we have the App component. Let's create the App component to its own file, App.js
```js
// src/App.js
import React from 'react
const App = () => <h1>Welcome to 30 Days Of React</h1>
```
We have to export the component to import it in another file. We can export it as a default or named export. In one file, we can make one default export and many named exports. First, let's implement it using name export and later in default export.
We just add the keyword export before _let_ or _const_ to make a named export.
```js
// src/App.js
import React from 'react
// named export in arrow function
export const App = () => <h1>Welcome to 30 Days Of React</h1>
```
Exporting in a function declaration, a regular function
```js
// src/App.js
import React from 'react
// named export in regular function, function declaration
export function App () {
return <h1>Welcome to 30 Days Of React</h1>
}
```
Now, let's import the App component from the App.js file to index.js.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { App } from './App'
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
We saw a named export and now let's implement it with default export. We can do it in two ways but it is recommended to use the second way if we are exporting components because sometimes we may bind a component with another higher order component.
```js
// src/App.js
import React from 'react
// export default in arrow function
export default const App = () => <h1>Welcome to 30 Days Of React</h1>
```
```js
// src/App.js
import React from 'react
// export default in arrow function
export default function App () {
return <h1>Welcome to 30 Days Of React</h1>
}
```
```js
// src/App.js
// Recommended for most of the cases
import React from 'react
const App = () => <h1>Welcome to 30 Days Of React</h1>
export default App
```
If a component is exported as default we do not need curly bracket during importing.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
If you remember, we created the following components so far and we have been putting them together. It is not easy to work like this. Now we will move them all components to a separate file.
```js
// index.js
import React from 'react'
import ReactDOM from 'react-dom'
import asabenehImage from './images'
import { countriesData } from './data/countries'
// Header component
class Header extends React.Component {
render() {
console.log(this.props.data)
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = this.props.data
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
}
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`
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>{formatedCapital}</p>
<p>
<span>{formatLanguage}: </span>
{languages.join(', ')}
</p>
<p>
<span>Population: </span>
{population.toLocaleString()}
</p>
<p>
<span>Currency: </span>
{currency}
</p>
</div>
</div>
)
}
// User Card Component
const UserCard = () => (
<div className='user-card'>
<img src={asabenehImage} alt='asabeneh image' />
<h2>Asabeneh Yetayeh</h2>
</div>
)
// Hexadecimal color generator
const hexaColor = () => {
let str = '0123456789abcdef'
let color = ''
for (let i = 0; i < 6; i++) {
let index = Math.floor(Math.random() * str.length)
color += str[index]
}
return '#' + color
}
const HexaColor = () => <div>{hexaColor()}</div>
const Message = ({ message }) => (
<div>
<h1>{message}</h1>
</div>
)
const Login = () => (
<div>
<h3>Please Login</h3>
</div>
)
const Welcome = (props) => (
<div>
<h1>Welcome to 30 Days Of React</h1>
</div>
)
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// TechList Component
// class base component
class TechList extends React.Component {
render() {
const { techs } = this.props
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
}
// Main Component
// Class Component
class Main extends React.Component {
render() {
const {
techs,
greetPeople,
handleTime,
loggedIn,
handleLogin,
message,
} = this.props
console.log(message)
const status = loggedIn ? <Welcome /> : <Login />
return (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList techs={this.props.techs} />
</ul>
{techs.length === 3 && (
<p>You have all the prerequisite courses to get started React</p>
)}
<div>
<Button
text='Show Time'
onClick={handleTime}
style={buttonStyles}
/>{' '}
<Button
text='Greet People'
onClick={greetPeople}
style={buttonStyles}
/>
{!loggedIn && <p>Please login to access more information about 30 Days Of React challenge</p>}
</div>
<div style={{ margin: 30 }}>
<Button
text={loggedIn ? 'Logout' : 'Login'}
style={buttonStyles}
onClick={handleLogin}
/>
<br />
{status}
</div>
<Message message={message} />
</div>
</main>
)
}
}
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: 3,
cursor: 'pointer',
fontSize: 22,
color: 'white',
margin: '0 auto',
}
// Footer Component
// Class component
class Footer extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<footer>
<div className='footer-wrapper'>
<p>Copyright {this.props.date.getFullYear()}</p>
</div>
</footer>
)
}
}
class App extends React.Component {
state = {
loggedIn: false,
techs: ['HTML', 'CSS', 'JS'],
message: 'Click show time or Greet people to change me',
}
handleLogin = () => {
this.setState({
loggedIn: !this.state.loggedIn,
})
}
showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return `${month} ${date}, ${year}`
}
handleTime = () => {
let message = this.showDate(new Date())
this.setState({ message })
}
greetPeople = () => {
let message = 'Welcome to 30 Days Of React Challenge, 2020'
this.setState({ message })
}
render() {
const data = {
welcome: '30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 9, 2020',
}
const techs = ['HTML', 'CSS', 'JavaScript']
return (
<div className='app'>
{this.state.backgroundColor}
<Header data={data} />
<Main
techs={techs}
handleTime={this.handleTime}
greetPeople={this.greetPeople}
loggedIn={this.state.loggedIn}
handleLogin={this.handleLogin}
message={this.state.message}
/>
<Footer date={new Date()} />
</div>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
```
## Components Folder
Inside the src directory will pull all the components
```sh
src
App.js
index.js
components
-auth
-Signup.js
-Signin.js
-Forgotpassword.js
-Resetpassord.js
header
-Header.js
footer
-Footer.js
assets
-images
-icnons
- fonts
styles
-button.js
-button.scss
utils
-random-id.js
-display-time.js
-generate-color.js
shared
-Button.js
-InputField.js
-TextAreaField.js
```
Let's create components directory inside src and inside components let's create header director. Create Header.js inside the header directory.
```js
// src/components/header/Header.js
import React from 'react'
const Header = (props) => {
return (
<header>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
export default Header
```
Similar to the Header let's move all the components to their respective files.
All the CSS files on index.html will moved into styles folder and after that each part has been split its respective file, try to check the styles folder.
## Fragments
Fragments are a way to avoid unnecessary parent element in JSX. Let's implement a fragment. We import fragment from react module. As you can see below, we imported React and fragment together by use a comma separation.
```js
import React, { Fragment } from 'react'
const Skills = () => {
return (
<Fragment>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</Fragment>
)
}
const RequiredSkills = () => {
return (
<ul>
<Skills />
</ul>
)
}
```
It is also possible to just extract the fragment module from React as shown below.
```js
import React from 'react'
const Skills = () => {
return (
<React.Fragment>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</React.Fragment>
)
}
const RequiredSkills = () => {
return (
<ul>
<Skills />
</ul>
)
}
```
In latest version of Reacts it also possible to write without extracting or importing using this signs(<> </>)
```js
import React from 'react'
// Recommended
const Skills = () => {
return (
<>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</>
)
}
const RequiredSkills = () => {
return (
<ul>
<Skills />
</ul>
)
}
```
When we make a class-based component we have been using React.Component instead we can just import the component and the code will look more clean. Let's see an example.
```js
import React from 'react'
// without importing the Component
// Not recommended
class App extends React.Component {
render() {
return <h1> 30 Days of React </h1>
}
}
```
```js
import React, { Component } from 'react'
// This is recommended
class App extends Component {
render() {
return <h1> 30 Days of React </h1>
}
}
```
Well done. Time to do some exercises for your brain and muscles.
# Exercises
## Exercises:Level 1
1. What is the importance of React Folder Structure and File Naming
2. How do you export file
3. How do you import file
4. Make a component of module and export it as named or default export
5. Make a component or module and import it
6. Change all the components you have to different folder structure
## Exercises:Level 2
1. Make a simple portfolio using the components we have created so far. Implement a dark mode by using the function we wrote on day 8 challenge.
## Exercises: Level 3
Coming
🎉 CONGRATULATIONS ! 🎉
[<< Day 9](../09_Day_Conditional_Rendering/09_conditional_rendering.md) | [Day 11 >>](../11_Day_Events/11_events.md)

@ -1,23 +0,0 @@
# 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*

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

@ -1,34 +0,0 @@
{
"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"
]
}
}

@ -1,20 +0,0 @@
<!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|Aldrich:300,400, 500|Oswald:300,400, 500|Raleway: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>
</head>
<body>
<div id="root"></div>
</body>
</html>

@ -1,65 +0,0 @@
import React from 'react'
import Header from './components/header/Header'
import Main from './components/main/Main'
import Footer from './components/footer/Footer'
import { countriesData } from './data/countries'
import asabenehImage from './assets/images/asabeneh.jpg'
import { showDate } from './utils/display-date-and-time'
class App extends React.Component {
state = {
loggedIn: false,
techs: ['HTML', 'CSS', 'JS'],
message: 'Click show time or Greet people to change me',
country: countriesData[1],
}
handleLogin = () => {
this.setState({
loggedIn: !this.state.loggedIn,
})
}
handleTime = () => {
let message = showDate(new Date())
this.setState({ message })
}
greetPeople = () => {
let message = 'Welcome to 30 Days Of React Challenge, 2020'
this.setState({ message })
}
render() {
const data = {
welcome: '30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: new Date(),
}
const techs = ['HTML', 'CSS', 'JavaScript']
const user = { ...data.author, image: asabenehImage }
return (
<div className='app'>
{this.state.backgroundColor}
<Header data={data} />
<Main
techs={techs}
handleTime={this.handleTime}
greetPeople={this.greetPeople}
loggedIn={this.state.loggedIn}
handleLogin={this.handleLogin}
message={this.state.message}
country={this.state.country}
user={user}
/>
<Footer date={new Date()} />
</div>
)
}
}
export default App

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save