# 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 ![](https://i.imgur.com/xNvTkbF.png) **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