# WEEK 4 - Front-End/ReactJS
###### tags: `WEB` `JS` `DIGITALIZE` `FRONTEND` `REACTJS`
## What is ReactJS?
- Free & open source Java script library
- Used for building user interfaces or UI components.
- Developed and maintained by Meta in addition community of individual developers and companies.
- Used for building SPA.
## Why ReactJS?
1. Small learning curve.
2. Component-based
3. Fast & snappy
4. Wide & active Community
5. Rich resources
## Hello, World!
Let's see an example of "Hello, World!" ReactJS application.
Github Repo: https://github.com/fadiramzi/cra-hello.git
## Environment Setup
- IDE (VSCode)
- Nodejs & NPM tool
Node.js® is a **JavaScript runtime** built on Chrome's V8 [JavaScript engine](https://blog.sessionstack.com/how-javascript-works-inside-the-v8-engine-5-tips-on-how-to-write-optimized-code-ac089e62b12e#:~:text=A%20JavaScript%20engine%20is%20a%20program%20or%20an%20interpreter%20which%20executes%20JavaScript%20code.%20A%20JavaScript%20engine%20can%20be%20implemented%20as%20a%20standard%20interpreter%2C%20or%20just-in-time%20compiler%20that%20compiles%20JavaScript%20to%20bytecode%20in%20some%20form.)
**It is:**
1. An open source server environment
2. Free
3. Runs on various platforms (Windows, Linux, Unix, Mac OS X, etc.)
4. Uses JavaScript on the server.
5. Uses asynchronous programming.
**What is NPM?**
NPM is a package manager for Node.js packages, or modules, The NPM program is installed on your computer when you install Node.js
Download:
https://nodejs.org/en/download/
## Create Hello, World! App
### Using CRA (Create React App)
Create React App is a comfortable environment for learning React, and is the best way to start building a new single-page application in React.
It sets up your development environment so that you can use the latest JavaScript features, provides a nice developer experience, and optimizes your app for production. You’ll need to have Node >= 14.0.0 and npm >= 5.6 on your machine. To create a project, run:
First install create-react-app globally in your machine with the following command:
```
npm i -g create-react-app
```
then use npx to use latest installed package from your machine locally, keep in mind, you need to make this package up to date.
```
npx create-react-app hello-app
cd hello-app
npm start
```
## React Project Structure
Let's illustrate default project direcories and files of a React application project

**Main directories & files:**
- **public**
- Favicon
- Entry point of the application (index.html file)
- logo images & manifest
- **src:** Contains all JS files, JSX components that will be compiled and bundled to an single bundled JS file.
- **node-modules:** contains all dependencies and code of installed packages which are used for development purposes only.
- **package.json (file)**
- **package-lock.json (file):** avoid changing it manually!
- **.gitignore (file)**
- **README.md**
## JSX
JSX stands for JavaScript XML. It is simply a syntax extension of JavaScript. It allows us to directly write HTML in React (within JavaScript code). It is easy to create a template using JSX in React.
**Example:**
```
const element = <h1>Hello, world!</h1>;
```
- Embedding Expressions in JSX
**Example:**
```
const name = 'Laith';
const element = <h1>Hello, {name}</h1>;
ReactDOM.render(
element,
document.getElementById('root')
);
```
- JSX with function
**Example:**
```
function getGreeting(user) {
if (user) {
return <h1>Hello, {user.firstName}!</h1>;
}
return <h1>Hello, There!</h1>;
}
```
- Specifying Attributes with JSX
You may use quotes to specify string literals as attributes:
Example:
```
const element = <div id="product"></div>;
```
You may also use curly braces to embed a JavaScript expression in an attribute, Example:
```
const element = <img src={user.profilePicture}></img>;
```
## Component
Components let you split the UI into independent, reusable pieces, and think about each piece in isolation.
Components are like JavaScript functions. They accept arbitrary inputs (called “props”) and return React elements describing what should appear on the screen.
Components come in two types, Class components and Function components.
Stateless Component
Example:
```
// Stateless component
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
```
Stateful Component
```
class Car extends React.Component {
constructor(props) {
super(props);
this.state = {brand: "Ford"};
}
render() {
return (
<div>
<h1>My {this.state.brand}</h1>
</div>
);
}
}
```
### User-defined component
We can define our custom component and use it as a normal tag.
Example:
```
function Welcome() {
return <h1>Hello, World</h1>;
}
const element = <Welcome />;
ReactDOM.render(
element,
document.getElementById('root')
);
```
### Props
Props stands for properties, used for passing data as key value from parant component to child component.
Example:
```
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="World"/>;
ReactDOM.render(
element,
document.getElementById('root')
);
```
### Composing Components
We can use a component inside another component!. Also we can pass props from component to another as we did by using Props.
Example:
```
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function RootEl(props)
{
return <div>
<Welcome name={props.name} />
</div>;
}
const RootEl = <RootEl name="world"/>;
ReactDOM.render(
RootEl,
document.getElementById('root')
);
```
### Extracting Components
Split components into smaller components.
Below component can be tricky to change because of all the nesting, and it is also hard to reuse individual parts of it. Let’s extract a few components from it.
Example:
```
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
```
Optimizing steps:
1. Extract Avatar
```
function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
```
```
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} />
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
```
2. Extract a UserInfo
```
function UserInfo(props) {
return (
<div className="UserInfo">
<Avatar user={props.user} />
<div className="UserInfo-name">
{props.user.name}
</div>
</div>
);
}
```
```
function Comment(props) {
return (
<div className="Comment">
<UserInfo user={props.author} />
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
```
Now, let's take a look at the component before & after optimization:
Before
```
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
```
After:
```
function Comment(props) {
return (
<div className="Comment">
<UserInfo user={props.author} />
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
```
## Looping Through An Array Within JSX
Example:
```
import React from 'react';
function List() {
const myArray = ['Ahmed', 'Fadi', 'Ammar', 'Aws', 'Zaid'];
return (
<div className="container">
<h1> Example of array iteration using map function </h1>
{myArray.map(val => (
<li>
{val}
</li>
))}
</div>
);
}
export default List;
```
Example:
```
import React from 'react';
function App() {
const PATIENTS = [
{
id:1,
full_name:"Ali Ahmed",
birth_date:"10/10/1999",
gender:"m",
phone:"+96477889654"
},
{
id:2,
full_name:"Ameer Saad",
birth_date:"10/10/2000",
gender:"m",
phone:"+96477809654"
},
{
id:3,
full_name:"Muna Ali",
birth_date:"10/10/1998",
gender:"f",
phone:"+964777809654"
}
]
return (
<div className="container">
<h1> Example of lopoping through array using map function </h1>
<table className="table table-bordered">
<tr>
<th>ID</th>
<th>Name</th>
<th>Phone</th>
<th>Gender</th>
</tr>
{patients.map((patient, index) => (
<tr data-index={index}>
<td>{patient.id}</td>
<td>{patient.full_name}</td>
<td>{patient.phone}</td>
<td>{patient.gender}</td>
</tr>
))}
</table>
</div>
);
}
export default App;
```
## State Management
State management is simply a way for sharing of data across components.
It is a JavaScript object that represents the part of a component that can change based on a resultant action of a user.
When a user performs an action in a typical React app, changes occur in the component's state.
Example:
```
const PATIENTS = [
{
id:1,
full_name:"Ali Ahmed",
birth_date:"10/10/1999",
gender:"m",
phone:"+96477889654"
},
{
id:2,
full_name:"Ameer Saad",
birth_date:"10/10/2000",
gender:"m",
phone:"+96477809654"
},
{
id:3,
full_name:"Muna Ali",
birth_date:"10/10/1998",
gender:"f",
phone:"+964777809654"
}
]
class Patients extends React.Component {
constructor(props) {
super(props);
this.state = {
patients: PATIENTS
};
}
render() {
return <div className="">
{
this.state.patients.map((item, index, lst)=>{
return <PCard data={item}/>
})
}
</div>
}
}
```
## Conditional
Conditionally render components.
### if Statement
We can use `if` inside a component before rendering
```
const PCard = (props)=>{
let {full_name,gender,phone,birth_date}=props;
let bgColor = gender == 'm'?'blue':'pink';
return <div style={{
backgroundColor:bgColor
}}>
<p>{full_name}</p>
<p>{gender}</p>
<p>{phone}</p>
<p>{birth_date}</p>
</div>
}
export default PCard;
```
## Handling Events
Let's add new button to enable the user add new static object to the list, note that we cannot update the array in the state directly, we must clone the array, update it seperately, then update the array in the state.
```
import React, { Component } from 'react';
import PCard from './PatientCard';
const PATIENTS = [
{
id:1,
full_name:"Ali Ahmed",
birth_date:"10/10/1999",
gender:"m",
phone:"+96477889654"
},
{
id:2,
full_name:"Ameer Saad",
birth_date:"10/10/2000",
gender:"m",
phone:"+96477809654"
},
{
id:3,
full_name:"Muna Ali",
birth_date:"10/10/1998",
gender:"f",
phone:"+964777809654"
}
]
class Patients extends Component {
constructor(props)
{
super(props)
this.state = {
patients: PATIENTS
};
}
addNew = (e)=>{
let pTemp = this.state.patients;
pTemp.push({
'birth_date':'10/10/2022',
'full_name':"Fadi Ramzi",
"phone":"+9647788996523",
"gender":'m',
'id':4
})
this.setState({
patients:pTemp
})
}
render() {
return <div className="">
<button onClick={this.addNew}>Add</button>
{
this.state.patients.map((item, index, lst)=>{
return <PCard data={item}/>
})
}
</div>
}
}
export default Patients;
```
## Forms
Just like in HTML, React uses forms to allow users to interact with the web page.
Adding Forms in React
You add a form with React like any other element:
```
function MyForm() {
return (
<form>
<label>Enter your name:
<input type="text" />
</label>
</form>
)
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
```
Example of managing Forms with functional component:
```
import { useState } from "react";
import ReactDOM from 'react-dom';
function MyForm() {
const [name, setName] = useState("");
return (
<form>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
</form>
)
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
```
Submitting Forms
You can control the submit action by adding an event handler in the onSubmit attribute for the `<form>`:
```
import { useState } from "react";
import ReactDOM from 'react-dom';
function MyForm() {
const [name, setName] = useState("");
const handleSubmit = (event) => {
event.preventDefault();
alert('The name you entered was: ${name}')
}
return (
<form onSubmit={handleSubmit}>
<label>Enter your name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<input type="submit" />
</form>
)
}
ReactDOM.render(<MyForm />, document.getElementById('root'));
```
## Task