FSD Week 5

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 59

FULL STACK DEVELOPMENT - WEEK 5

INTRODUCTION TO REACT
What is React ?
React is a declarative, efficient, and flexible JavaScript library for building user
interfaces. ReactJS is an open-source, component-based front-end library responsible
only for the view layer of the application. It is maintained by Facebook.

Setting up React development environment - Installing Node.js


Step 1: Install NodeJS. You may visit the official download link of NodeJS to download
and install the LTS version of NodeJS. Once we have set up NodeJS on our PC, the next
thing we need to do is set up React Boilerplate.

Step 2: After installation of node js successfully.We will install the boilerplate


globally. Run the below command in your terminal or command prompt to install the
React Boilerplate.
> npm install -g create-react-app
After running the above command and successfully installing the boilerplate your
linux terminal will show some output as shown in the below image:

JB PORTALS 1
FULL STACK DEVELOPMENT - WEEK 5
Now after successfully installing the boilerplate the next thing we will do is create our
React app. We can use the create-react-app command for creating an app to React.
Run the below command to create a new project

> create-react-app my-app


The above command will create the app name my-app as shown in the image below

:
You can run the project by typing the command cd my-app.

> cd my-app
> npm start
It will give you the output in the terminal as shown in the image below :

Now you can view your app in the browser as shown in the image below :

JB PORTALS 2
FULL STACK DEVELOPMENT - WEEK 5

Let’s have a look at the directory created by the above process:

In the above directory, you can see a number of files. The main files we will be
working on within the basic course are index.html and index.js. The index.html file will
have a div element with id = “root”, inside which everything will be rendered and all
of our React code will be inside the index.js file.
You can checkout the React.js docs for advanced setup.

JB PORTALS 3
FULL STACK DEVELOPMENT - WEEK 5
What is the Folder Structure for React Project?
The folder structure looks like this.
 Assets Folder
 Layouts Folder
 Components Folder
 Pages Folder
 Middleware Folder
 Routes Folder
 Config Folder
 Services Folder
 Utils Folder

Assets Folder
As the name says, it contains assets of our project. It consists of images and
styling files. Here we can store our global styles. We are centralizing the project so we
can store the page-based or component-based styles over here. But we can even keep
style according to the pages folder or component folder also. But that depends on
developer comfortability.

Layouts Folder
As the name says, it contains layouts available to the whole project like header,
footer, etc. We can store the header, footer, or sidebar code here and call it.

JB PORTALS 4
FULL STACK DEVELOPMENT - WEEK 5
Components Folder
Components are the building blocks of any react project. This folder consists of
a collection of UI components like buttons, modals, inputs, loader, etc., that can be
used across various files in the project. Each component should consist of a test file
to do a unit test as it will be widely used in the project.

Pages Folder
The files in the pages folder indicate the route of the react application. Each file
in this folder contains its route. A page can contain its subfolder. Each page has its
state and is usually used to call an async operation. It usually consists of various
components grouped.

Middleware Folder
This folder consists of middleware that allows for side effects in the
application. It is used when we are using redux with it. Here we keep all our custom
middleware.

Routes Folder
This folder consists of all routes of the application. It consists of private,
protected, and all types of routes. Here we can even call our sub-route.

Config Folder
This folder consists of a configuration file where we store environment
variables in config.js. We will use this file to set up multi-environment configurations
in your application.

Services Folder
This folder will be added if we use redux in your project. Inside it, there are 3
folders named actions, reducers, and constant subfolders to manage states. The
actions and reducers will be called in almost all the pages, so create actions, reducers
& constants according to pages name.

Utils Folder
Utils folder consists of some repeatedly used functions that are commonly used
in the project. It should contain only common js functions & objects like dropdown
options, regex condition, data formatting, etc.

JB PORTALS 5
FULL STACK DEVELOPMENT - WEEK 5

Installing ReactJS using webpack and babel


Webpack is a module bundler (manages and loads independent modules). It
takes dependent modules and compiles them to a single (file) bundle. You can use this
bundle while developing apps using command line or, by configuring it using
webpack.config file.
Babel is a JavaScript compiler and transpiler. It is used to convert one source
code to other. Using this you will be able to use the new ES6 features in your code
where, babel converts it into plain old ES5 which can be run on all browsers.
Step 1 - Create the Root Folder
Create a folder with name reactApp on the desktop to install all the required files,
using the mkdir command.
C:\Users\username\Desktop>mkdir reactApp
C:\Users\username\Desktop>cd reactApp
To create any module, it is required to generate the package.json file. Therefore, after
Creating the folder, we need to create a package.json file. To do so you need to run
the npm init command from the command prompt.
C:\Users\username\Desktop\reactApp>npm init
This command asks information about the module such as packagename, description,
author etc. you can skip these using the –y option.

C:\Users\username\Desktop\reactApp>npm init -y
Wrote to C:\reactApp\package.json:
{
"name": "reactApp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
JB PORTALS 6
FULL STACK DEVELOPMENT - WEEK 5
Step 2 - install React and react dom
Since our main task is to install ReactJS, install it, and its dom packages, using install
react and react-dom commands of npm respectively. You can add the packages we
install, to package.json file using the --save option.
C:\Users\Tutorialspoint\Desktop\reactApp>npm install react --save
C:\Users\Tutorialspoint\Desktop\reactApp>npm install react-dom --save
Or, you can install all of them in single command as −
C:\Users\username\Desktop\reactApp>npm install react react-dom --save

Step 3 - Install webpack


Since we are using webpack to generate bundler install webpack, webpack-dev-
server and webpack-cli.
C:\Users\username\Desktop\reactApp>npm install webpack --save
C:\Users\username\Desktop\reactApp>npm install webpack-dev-server --save
C:\Users\username\Desktop\reactApp>npm install webpack-cli --save
Or, you can install all of them in single command as −
C:\Users\username\Desktop\reactApp>npm install webpack webpack-dev-server
webpack-cli --save

Step 4 - Install babel


Install babel, and its plugins babel-core, babel-loader, babel-preset-env, babel-preset-
react and, html-webpack-plugin
C:\Users\username\Desktop\reactApp>npm install babel-core --save-dev
C:\Users\username\Desktop\reactApp>npm install babel-loader --save-dev
C:\Users\username\Desktop\reactApp>npm install babel-preset-env --save-dev
C:\Users\username\Desktop\reactApp>npm install babel-preset-react --save-dev
C:\Users\username\Desktop\reactApp>npm install html-webpack-plugin --save-
dev
Or, you can install all of them in single command as −
C:\Users\username\Desktop\reactApp>npm install babel-core babel-loader babel-
preset-env
babel-preset-react html-webpack-plugin --save-dev
JB PORTALS 7
FULL STACK DEVELOPMENT - WEEK 5
Step 5 - Create the Files
To complete the installation, we need to create certain files namely, index.html,
App.js, main.js, webpack.config.js and, .babelrc. You can create these files manually
or, using command prompt.
C:\Users\username\Desktop\reactApp>type nul > index.html
C:\Users\username\Desktop\reactApp>type nul > App.js
C:\Users\username\Desktop\reactApp>type nul > main.js
C:\Users\username\Desktop\reactApp>type nul > webpack.config.js
C:\Users\username\Desktop\reactApp>type nul > .babelrc

Step 6 - Set Compiler, Server and Loaders


Open webpack-config.js file and add the following code. We are setting
webpack entry point to be main.js. Output path is the place where bundled app will
be served. We are also setting the development server to 8001 port. You can choose
any port you want.

webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: './main.js',
output: {
path: path.join(__dirname, '/bundle'),
filename: 'index_bundle.js'
},
devServer: {
inline: true,
port: 8001
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
JB PORTALS 8
FULL STACK DEVELOPMENT - WEEK 5
query: {
presets: ['es2015', 'react']
}
}
]
},
plugins:[
new HtmlWebpackPlugin({
template: './index.html'
})
]
}
Open the package.json and delete "test" "echo \"Error: no test specified\"
&& exit 1" inside "scripts" object. We are deleting this line since we will not do any
testing in this tutorial. Let's add the start and build commands instead.
"start": "webpack-dev-server --mode development --open --hot",
"build": "webpack --mode production"

Step 7 - index.html
This is just regular HTML. We are setting div id = "app" as a root element for our app
and adding index_bundle.js script, which is our bundled app file.

<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<title>React App</title>
</head>
<body>
<div id = "app"></div>
<script src = 'index_bundle.js'></script>
</body>
</html>

JB PORTALS 9
FULL STACK DEVELOPMENT - WEEK 5
Step 8 − App.jsx and main.js
This is the first React component. We will explain React components in depth
in a subsequent chapter. This component will render Hello World.
App.js
import React, { Component } from 'react';
class App extends Component{
render(){
return(
<div>
<h1>Hello World</h1>
</div>
);
}
}
export default App;
We need to import this component and render it to our root App element, so
we can see it in the browser.
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';

ReactDOM.render(<App />, document.getElementById('app'));

Note − Whenever you want to use something, you need to import it first. If you want
to make the component usable in other parts of the app, you need to export it after
creation and import it in the file where you want to use it.
Create a file with name .babelrc and copy the following content to it.
{
"presets":["env", "react"]
}

Step 9 - Running the Server


The setup is complete and we can start the server by running the following command.
C:\Users\username\Desktop\reactApp>npm start
It will show the port we need to open in the browser. In our case, it
is http://localhost:8001/. After we open it, we will see the following output.

JB PORTALS 10
FULL STACK DEVELOPMENT - WEEK 5

Step 10 - Generating the bundle


Finally, to generate the bundle you need to run the build command in the
command prompt as −
C:\Users\Tutorialspoint\Desktop\reactApp>npm run build
This will generate the bundle in the current folder as shown below.

Using the create-react-app command


Instead of using webpack and babel you can install ReactJS more simply by
installing create-react-app.

Step 1 - install create-react-app


Browse through the desktop and install the Create React App using command prompt
as shown below −
C:\Users\Tutorialspoint>cd C:\Users\Tutorialspoint\Desktop\
C:\Users\Tutorialspoint\Desktop>npx create-react-app my-app
This will create a folder named my-app on the desktop and installs all the required
files in it.

JB PORTALS 11
FULL STACK DEVELOPMENT - WEEK 5

Step 2 - Delete all the source files


Browse through the src folder in the generated my-app folder and remove all the files
in it as shown below −
C:\Users\Tutorialspoint\Desktop>cd my-app/src
C:\Users\Tutorialspoint\Desktop\my-app\src>del *
C:\Users\Tutorialspoint\Desktop\my-app\src\*, Are you sure (Y/N)? y

Step 3 - Add files


Add files with names index.css and index.js in the src folder as −
C:\Users\Tutorialspoint\Desktop\my-app\src>type nul > index.css
C:\Users\Tutorialspoint\Desktop\my-app\src>type nul > index.js
In the index.js file add the following code
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

Step 4 - Run the project


Finally, run the project using the start command.
npm start

JB PORTALS 12
FULL STACK DEVELOPMENT - WEEK 5
INTRODUCTION TO 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, but it is not a simple template language instead
it comes with the full power of JavaScript. It is faster than normal JavaScript as it
performs optimizations while translating to regular JavaScript. Instead of
separating the markup and logic in separated files, React uses components for this
purpose. We will learn about components in detail in further articles.

Characteristics of JSX:
 JSX is not mandatory to use there are other ways to achieve the same thing but
using JSX makes it easier to develop react application.
 JSX allows writing expression in { }. The expression can be any JS expression or
React variable.
 To insert a large block of HTML we have to write it in a parenthesis i.e, ().
 JSX produces react elements.
 JSX follows XML rule.
 After compilation, JSX expressions become regular JavaScript function calls.
 JSX uses camelcase notation for naming HTML attributes. For example, tabindex
in HTML is used as tabIndex in JSX.

Let us see a sample JSX(Java Script XML) code:


const ele = <h1>This is sample JSX</h1>;
The above code snippet somewhat looks like HTML and it also uses a
JavaScript-like variable but is neither HTML nor JavaScript, it is JSX. JSX is basically a
syntax extension of regular JavaScript and is used to create React elements. These
elements are then rendered to the React DOM. We will learn about rendering and
DOM in the next article in detail.

Expressions in JSX
In React we are allowed to use normal JavaScript expressions with JSX. To embed any
JavaScript expression in a piece of code written in JSX we will have to wrap that
expression in curly braces {}. Consider the below program, written in the index.js file:
import React from 'react';
import ReactDOM from 'react-dom';
const name = "Learner";
const element = <h1>Hello,
{ name }.Welcome to React Course.< /h1>;
ReactDOM.render(
element,
document.getElementById("root")
);

JB PORTALS 13
FULL STACK DEVELOPMENT - WEEK 5
Output:

In the above program we have embedded the javascript expression const name
= “Learner”; in our JSX code. We embed the use of any JavaScript expression in JSX by
wrapping them in curly braces except if-else statements. But we can use conditional
statements instead of if-else statements in JSX. Below is the example where
conditional expressing is embedded in JSX:

import React from 'react';


import ReactDOM from 'react-dom';

let i = 1;
const element = <h1>{ (i == 1) ? 'Hello World!' : 'False!' } < /h1>;
ReactDOM.render(
element,
document.getElementById("root")
);
Output:

In the above example, the variable i is checked if for the value 1. As it equals 1
so the string ‘Hello World!’ is returned to the JSX code. If we modify the value of the
variable i then the string ‘False’ will be returned.

Specifying Attributes with JSX


JSX allows us to use attributes with the HTML elements just like we do with
normal HTML. But instead of the normal naming convention of HTML, JSX uses
camelcase convention for attributes. For example, class in HTML becomes className
in JSX. The main reason behind this is that some attribute names in HTML like ‘class’
are reserved keywords in JavaScripts.
JB PORTALS 14
FULL STACK DEVELOPMENT - WEEK 5
So, in order to avoid this problem, JSX uses the camel case naming convention
for attributes. We can also use custom attributes in JSX. In the below example, we can
see the defining attributes in the JSX elements.

import React from 'react';


import ReactDOM from 'react-dom';

const element = <div><h1 className = "hello">Hello Geek</h1><h2


data-sampleAttribute="sample">Custom attribute</h2></div>;

ReactDOM.render(
element,
document.getElementById("root")
);

Specifying attribute values:


JSX allows us to specify attribute values in two ways:

1. As for string literals: We can specify the values of attributes as hard-coded strings
using quotes:
const ele = <h1 className = "firstAttribute">Hello!</h1>;
2. As expressions: We can specify attributes as expressions using curly braces {}:
const ele = <h1 className = {varName}>Hello!</h1>;

Specifying Children with JSX


Consider a situation where you want to render multiple tags at a time. To do
this we need to wrap all of this tag under a parent tag and then render this parent
element to the HTML. All the subtags are called child tags or children of this parent
element. Notice in the below example how we have wrapped h1, h2, and h3 tags under
a single div element and rendered them to HTML:

import React from 'react';


import ReactDOM from 'react-dom';

const element = <div><h1>This is Heading 1 </h1>


<h2>This is Heading 2</h2 >
<h3>This is Heading 3 </h3>
</div > ;
ReactDOM.render(
element,
document.getElementById("root"));
JB PORTALS 15
FULL STACK DEVELOPMENT - WEEK 5
Output:

Rendering Elements
In order to render any element into the Browser DOM, we need to have a
container or root DOM element. It is almost a convention to have a div element with
the id=”root” or id=”app” to be used as the root DOM element. Let’s suppose our
index.html file has the following statement inside it.

<div id="root"></div>
Filename App.js: Now, in order to render a simple React Element to the root node,
we must write the following in the App.js file.

import React,{ Component } from 'react';

class App extends Component {


render() {
return (
<div>
<h1>Welcome to React Course From JB PORTALS</h1>
</div>
);
}
}
Output:

JB PORTALS 16
FULL STACK DEVELOPMENT - WEEK 5
DOM (Document Object Model)
DOM, abbreviated as Document Object Model, is a World Wide Web
Consortium standard logical representation of any webpage. In easier words, DOM is
a tree-like structure that contains all the elements and it’s properties of a website as
its nodes. DOM provides a language-neutral interface that allows accessing and
updating of the content of any element of a webpage.

 React DOM
ReactDOM is a package that provides DOM specific methods that can be used at
the top level of a web app to enable an efficient way of managing DOM elements of
the web page. ReactDOM provides the developers with an API containing the
following methods and a few more.
 render()
 findDOMNode()
 unmountComponentAtNode()
 hydrate()
 createPortal()
To use the ReactDOM in any React web app we must first import ReactDOM from
the react-dom package by using the following code snippet:
Import ReactDOM from ‘react-dom’;

render() Function
This is one of the most important methods of ReactDOM. This function is used
to render a single React Component or several Components wrapped together in a
Component or a div element. This function uses the efficient methods of React for
updating the DOM by being able to change only a subtree, efficient diff methods, etc.
Syntax:
ReactDOM.render(element, container, callback)

Parameters: This method can take a maximum of three parameters as described


below.
 element: This parameter expects a JSX expression or a React Element to be
rendered.
 container: This parameter expects the container in which the element has to
be rendered.
 callback: This is an optional parameter that expects a function that is to be
executed once the render is complete.

 React Virtual DOM


Virtual DOM in React is a “virtual” representation of the actual DOM. It is
nothing but an object created to replicate the actual DOM. Unlike the actual DOM, the
virtual DOM is cheap to create because it doesn’t write to the screen. It is only
available as a strategy to prevent a redraw of unnecessary page elements during re-
render.
JB PORTALS 17
FULL STACK DEVELOPMENT - WEEK 5
React Components
What is Components ?
A Component is one of the core building blocks of React. In other words, we can
say that every application you will develop in React will be made up of pieces called
components. Components make the task of building UIs much easier. You can see a UI
broken down into multiple individual pieces called components and work on them
independently and merge them all in a parent component which will be your final UI.
You can see in the below image we have broken down the UI of GeeksforGeeks’s
homepage into individual components.

Function and Class Components


1. Functional Components: Functional components are simply javascript functions.
We can create a functional component in React by writing a javascript function. These
functions may or may not receive data as parameters, we will discuss this later in the
tutorial. Below example shows a valid functional component in React:
const Democomponent=()=>
{
return <h1>Welcome Message!</h1>;
}
2. Class Components: The class components are a little more complex than the
functional components. The functional components are not aware of the other
components in your program whereas the class components can work with each
other. We can pass data from one class component to other class components. We can
use JavaScript ES6 classes to create class-based components in React. Below example
shows a valid class-based component in React:

JB PORTALS 18
FULL STACK DEVELOPMENT - WEEK 5
class Democomponent extends React.Component
{
render(){
return <h1>Welcome Message!</h1>;
}
}
Rendering a Component
React is also capable of rendering user-defined components. To render a
component in React we can initialize an element with a user-defined component and
pass this element as the first parameter to ReactDOM.render() or directly pass the
component as the first argument to the ReactDOM.render() method. Below syntax
shows how to initialize a component to an element:
const elementName = <ComponentName />;

In the above syntax, the ComponentName is the name of the user-defined component.

Note: The name of a component should always start with a capital letter. This is done
to differentiate a component tag with html tags.

Below example renders a component named Welcome to the screen:


Open your index.js file from your project directory, and make the given below
changes:
import React from 'react';
import ReactDOM from 'react-dom';

// This is a functional component


const Welcome=()=>
{
return <h1>Hello World!</h1>
}
ReactDOM.render(
<Welcome />,
document.getElementById("root")
);
Output:

JB PORTALS 19
FULL STACK DEVELOPMENT - WEEK 5

Let us see step-wise what is happening in the above example:


1. We call the ReactDOM.render() as the first parameter.

2. React then calls the component Welcome, which returns <h1>Hello World!</h1>;
as the result.

3. Then the ReactDOM efficiently updates the DOM to match with the returned
element and renders that element to the DOM element with id as “root”.

Composing Components
This is the way of re-using the same user defined component again and again
for a specific purpose. In the below example, we are using Greeting component in
App.js file to render multiple times.
const Greeting = ()=>{
return <h1>Hello From React Greeting !</h1>;
}
export default function App() {
return (
<div>
<Greeting/>
<Greeting/>
<Greeting/>
</div>
); }
In the above example we are using Greeting component 3 times in App component.
Output:

Create Your First React Component


1. You can use any of the methods either functional or class base component to create
your first component.

2. Component name must be start with capital letter to differentiate between DOM
elements and user defined components.

3. Component must return single node element.

JB PORTALS 20
FULL STACK DEVELOPMENT - WEEK 5
In the below example we are creating Button Componet with static label.
const Button = ()=>{
return <div>Button Label</div>;
}
You can render this Button by referring rendering of component method.In the below
example we are using this Button Component in App component to render it on
the DOM.
export default function App() {
return (
<div>
<Button/>
</div>
); }
Output:

REFERENCE LINK: https://www.freecodecamp.org/news/how-to-write-your-first-


react-js-component-d728d759cabc/

 Props and State


What are props?
Props is short for properties and they are used to pass data between React
components. React’s data flow between components is uni-directional (from parent
to child only).
REFERENCE LINK: https://www.youtube.com/watch?v=KvapOdsFK5A

How do you pass data with props?


Here is an example of how data can be passed by using props:
class ParentComponent extends Component {
render() {
return (
<ChildComponent name="First Child" />
);
}
}
const ChildComponent = (props) => {
return <p>{props.name}</p>;
};

JB PORTALS 21
FULL STACK DEVELOPMENT - WEEK 5

Firstly, we need to define/get some data from the parent component and assign it to
a child component’s “prop” attribute.
<ChildComponent name="First Child" />
“Name” is a defined prop here and contains text data. Then we can pass data with
props like we’re giving an argument to a function:

const ChildComponent = (props) => {


// statements
};
And finally, we use dot notation to access the prop data and render it:
return <p>{props.name}</p>;

What is state?
React has another special built-in object called state, which allows components to
create and manage their own data. So unlike props, components cannot pass data
with state, but they can create and manage it internally.
Here is an example showing how to use state:
class Test extends React.Component {
constructor() {
this.state = {
id: 1,
name: "test"
};
}
render() {
return (
<div>
<p>{this.state.id}</p>
<p>{this.state.name}</p>
</div>
);
}
}

JB PORTALS 22
FULL STACK DEVELOPMENT - WEEK 5
How do you update a component’s state?
State should not be modified directly, but it can be modified with a special
method called setState( ).
this.state.id = “2020”; // wrong
this.setState({ // correct
id: "2020"});
What happens when state changes?
OK, why must we use setState( )? Why do we even need the state object itself?
If you’re asking these questions, don't worry – you’ll understand state soon :) Let me
answer.

A change in the state happens based on user-input, triggering an event, and so


on. Also, React components (with state) are rendered based on the data in the state.
State holds the initial information.

So when state changes, React gets informed and immediately re-renders the
DOM – not the whole DOM, but only the component with the updated state. This
is one of the reasons why React is fast.

And how does React get notified? You guessed it: with setState( ). The setState(
) method triggers the re-rendering process for the updated parts. React gets
informed, knows which part(s) to change, and does it quickly without re-rendering
the whole DOM.

In summary, there are 2 important points we need to pay attention to when


using state:
 State shouldn’t be modified directly – the setState( ) should be used
 State affects the performance of your app, and therefore it shouldn’t be used
unnecessarily
What are the differences between props and state?
Finally, let’s recap and see the main differences between props and state:
 Components receive data from outside with props, whereas they can create and
manage their own data with state
 Props are used to pass data, whereas state is for managing data
 Data from props is read-only, and cannot be modified by a component that is
receiving it from outside
 State data can be modified by its own component, but is private (cannot be
accessed from outside)
 Props can only be passed from parent component to child (unidirectional flow)
 Modifying state should happen with the setState ( ) method

JB PORTALS 23
FULL STACK DEVELOPMENT - WEEK 5
Communication between components using props
React is a component-based UI library. When the UI is split into small, focused
components, they can do one job and do it well. But in order to build up a system into
something that can accomplish an interesting task, multiple components are needed.
These components often need to work in coordination together and, thus, must be
able to communicate with each other. Data must flow between them.

React components are composed in a hierarchy that mimics the DOM tree
hierarchy that they are used to create. There are those components that are higher
(parents) and those components that are lower (children) in the hierarchy. Let's take
a look at the directional communication and data flow that React enables between
components.

From Parent to Child with Props


The simplest data flow direction is down the hierarchy, from parent to child.
React's mechanism for accomplishing this is called props. A React component is a
function that receives a parameter called props. Props is a bag of data, an object that
can contain any number of fields.

If a parent component wants to feed data to a child component, it simply passes


it via props. Let's say that we have a BookList component that contains data for a list
of books. As it iterates through the book list at render time, it wants to pass the details
of each book in its list to the child Book component. It can do that through props.
These props are passed to the child component as attributes in JSX:

function BookList() {
const list = [
{ title: 'A Christmas Carol', author: 'Charles Dickens' },
{ title: 'The Mansion', author: 'Henry Van Dyke' },
// ...
]

return (
<ul>
{list.map((book, i) => <Book title={book.title} author={book.author}
key={i} />)}
</ul>
)
}

Then the Book component can receive and use those fields as contained in
the props parameter to its function:

JB PORTALS 24
FULL STACK DEVELOPMENT - WEEK 5
function Book(props) {
return (
<li>
<h2>{props.title</h2>
<div>{props.author}</div>
</li>
)
}

Favor this simplest form of data passing whenever it makes sense.


There is a limitation here, however, because props are immutable. Data that is passed
in props should never be changed. But then how does a child communicate back to its
parent component? One answer is callbacks.

From Child to Parent with Callbacks


For a child to talk back to a parent (unacceptable, I know!), it must first receive
a mechanism to communicate back from its parent. As we learned, parents pass data
to children through props. A "special" prop of type function can be passed down to a
child. At the time of a relevant event (eg, user interaction) the child can then call this
function as a callback.

Let's say that a book can be edited from a BookTitle component:

function BookTitle(props) {
return (
<label>
Title:
<input onChange={props.onTitleChange} value={props.title} />
</label>
)
}

It receives a onTitleChange function in the props, sent from its parent. It binds
this function to the onChange event on the <input /> field. When the input changes, it
will call the onTitleChange callback, passing the change Event object. Because the
parent, BookEditForm, has reference to this function, it can receive the arguments
that are passed to the function:

import React, { useState } from 'react'

function BookEditForm(props) {
const [title, setTitle] = useState(props.book.title)
function handleTitleChange(evt) {
setTitle(evt.target.value)
}
JB PORTALS 25
FULL STACK DEVELOPMENT - WEEK 5
return (
<form>
<BookTitle onTitleChange={handleTitleChange} title={title} />
</form>
)
}

In this case, the parent passed handleTitleChange, and when it's called, it sets
the internal state based on the value of evt.target.value -- a value that has come as a
callback argument from the child component. There are some cases, however, when
data sent through props might not be the best option for communicating between
components. For these cases, React provides a mechanism called context.

From Parent to Child with Context


If we desire something to be globally available -- in many components and
levels in the hierarchy -- props passing has the potential to be cumbersome. Think of
some data that we might like to broadcast to all child components that they react to
wherever they are, such as theming data. Instead of passing theme props to every
component down the tree or a subtree in the hierarchy, we can define a theme context
to be provided at the top and then consume it in whichever child needs it down the
line.
Let's say we went back to the example of a list of books in BookList and had a
parent component above that called BookPage. In that component we could provide
a context for the theme:

const ThemeContext = React.createContext('dark')

function BookPage() {
return (
<ThemeContext.Provider value="light">
<BookList />
</ThemeContext.Provider>
)
}

The ThemeContext need only be created once and, thus, is created outside the
component function. It is given a default of "dark" as a fallback theme name. The
context object contains a Provider function which we wrap our rendered child
component in. We can specify a value to override the default theme. Here, we are
saying our BookPage will always show the "light" theme. Note also that BookList does
not receive any theme props. We can leave its implementation as-is. But let's say that
we want our Book component to respond to theming. We could adjust it to something
like:

JB PORTALS 26
FULL STACK DEVELOPMENT - WEEK 5
import React, { useContext } from 'react'

function Book(props) {
const theme = useContext(ThemeContext)
const styles = {
dark: { background: 'black', color: 'white' },
light: { background: 'white', color: 'black' }
}
return (
<li style={styles[theme]}>
<h2>{props.title</h2>
<div>{props.author}</div>
</li>
)
}

Book needs to have access to the ThemeContext object created next


to BookPage, and that context object is fed to the useContext hook. From there, we
create a simple styles map and select the appropriate styling based on the value
of theme. Based on the value of theme provided in BookPage, we'll have a black color
on white background styling shown here.
The thing that's special about context is that theme did not come from props but
rather was simply available because a parent component provided it to any and all
children which used it.

Component Life Cycle Methods


REFERENCE LINK: https://reactjs.org/docs/react-component.html
Each component has several “lifecycle methods” that you can override to run code
at particular times in the process. We have seen so far that React web apps are
actually a collection of independent components that run according to the
interactions made with them. Every React Component has a lifecycle of its own,
lifecycle of a component can be defined as the series of methods that are invoked in
different stages of the component’s existence. A React Component can go through
four stages of its life as follows.

 Initialization: This is the stage where the component is constructed with the
given Props and default state. This is done in the constructor of a Component
Class.
 Mounting: Mounting is the stage of rendering the JSX returned by the render
method itself.
 Updating: Updating is the stage when the state of a component is updated and
the application is repainted.
 Unmounting: As the name suggests Unmounting is the final step of the
component lifecycle where the component is removed from the page.
JB PORTALS 27
FULL STACK DEVELOPMENT - WEEK 5
React provides the developers a set of predefined functions that if present is
invoked around specific events in the lifetime of the component. Developers are
supposed to override the functions with desired logic to execute accordingly. We
have illustrated the gist in the following diagram.

Functions of each Phase of Lifecycle


1. Initialization: In this phase, the developer has to define the props and initial
state of the component this is generally done in the constructor of the
component. The following code snippet describes the initialization process.

class Clock extends React.Component {


constructor(props)
{
// Calling the constructor of
// Parent Class React.Component
super(props);

// Setting the initial state


this.state = { date : new Date() };
}
}
2. Mounting:
Mounting is the phase of the component lifecycle when the initialization of
the component is completed and the component is mounted on the DOM and
rendered for the first time on the webpage. Now React follows a default procedure
in the Naming Conventions of these predefined functions where the functions
containing “Will” represents before some specific phase and “Did” represents after
the completion of that phase.

JB PORTALS 28
FULL STACK DEVELOPMENT - WEEK 5
The mounting phase consists of two such predefined functions as described below.

 componentWillMount() Function: As the name clearly suggests, this function


is invoked right before the component is mounted on the DOM i.e. this function gets
invoked once before the render() function is executed for the first time.

 render() Function: The render() method is the only required method in a class
component.

When called, it should examine this.props and this.state and return one of the
following types:

React elements. Typically created via JSX. For example, <div /> and <MyComponent
/> are React elements that instruct React to render a DOM node, or another user-
defined component, respectively.

Arrays and fragments. Let you return multiple elements from render. See the
documentation on fragments for more details.

Portals. Let you render children into a different DOM subtree. See the documentation
on portals for more details.

String and numbers. These are rendered as text nodes in the DOM.

Booleans or null or undefined. Render nothing. (Mostly exists to support return test
&& <Child /> pattern, where test is boolean).

The render() function should be pure, meaning that it does not modify
component state, it returns the same result each time it’s invoked, and it does not
directly interact with the browser.

 componentDidMount() Function: Similarly as the previous one this function is


invoked right after the component is mounted on the DOM i.e. this function gets
invoked once after the render() function is executed for the first time

3. Updation:
React is a JS library that helps create Active web pages easily. Now active web
pages are specific pages that behave according to their user. For example, let’s take
the GeeksforGeeks {IDE} webpage, the webpage acts differently with each user. User
A might write some code in C in the Light Theme while another User may write a
Python code in the Dark Theme all at the same time.

JB PORTALS 29
FULL STACK DEVELOPMENT - WEEK 5
This dynamic behavior that partially depends upon the user itself makes the
webpage an Active webpage. Now how can this be related to Updation? Updation is
the phase where the states and props of a component are updated followed by some
user events such as clicking, pressing a key on the keyboard, etc.

The following are the descriptions of functions that are invoked at different
points of Updation phase.

 componentWillReceiveProps() Function: This is a Props exclusive Function


and is independent of States. This function is invoked before a mounted
component gets its props reassigned. The function is passed the new set of Props
which may or may not be identical to the original Props. Thus checking is a
mandatory step in this regard. The following code snippet shows a sample use-
case.
componentWillReceiveProps(newProps)
{
if (this.props !== newProps) {
console.log(" New Props have been assigned ");
// Use this.setState() to rerender the page.
}
}
 setState() Function: This is not particularly a Lifecycle function and can be
invoked explicitly at any instant. This function is used to update the state of a
component. You may refer to this article for detailed information.

 shouldComponentUpdate() Function: By default, every state or props update


re-render the page but this may not always be the desired outcome, sometimes
it is desired that updating the page will not be repainted. The
shouldComponentUpdate() Function fulfills the requirement by letting React
know whether the component’s output will be affected by the update or not.
shouldComponentUpdate() is invoked before rendering an already mounted
component when new props or state are being received. If returned false then
the subsequent steps of rendering will not be carried out. This function can’t be
used in the case of forceUpdate(). The Function takes the new Props and new
State as the arguments and returns whether to re-render or not.

 componentWillUpdate() Function: As the name clearly suggests, this function


is invoked before the component is rerendered i.e. this function gets invoked
once before the render() function is executed after the updation of State or Props.

 componentDidUpdate() Function: Similarly this function is invoked after the


component is rerendered i.e. this function gets invoked once after the render()
function is executed after the updation of State or Props.
JB PORTALS 30
FULL STACK DEVELOPMENT - WEEK 5
4. Unmounting Phase:
This is the final phase of the lifecycle of the component that is the phase of
unmounting the component from the DOM.

The following function is the sole member of this phase.


 componentWillUnmount() Function: This function is invoked before the
component is finally unmounted from the DOM i.e. this function gets invoked
once before the component is removed from the page and this denotes the end
of the lifecycle.

We have so far discussed every predefined function there was in the lifecycle of
the component, and we have also specified the order of execution of the function.
Let us now see one final example to finish the article while revising what’s discussed
above.

First, create a react app and edit your index.js file from the src folder.
src index.js:
import React from 'react';
import ReactDOM from 'react-dom';

class Test extends React.Component {


constructor(props)
{
super(props);
this.state = { hello : "World!" };
}

componentWillMount()
{
console.log("componentWillMount()");
}

componentDidMount()
{
console.log("componentDidMount()");
}

changeState()
{
this.setState({ hello : "Geek!" });
}

render()
{

JB PORTALS 31
FULL STACK DEVELOPMENT - WEEK 5
return (
<div>
<h1>GeeksForGeeks.org, Hello{ this.state.hello }</h1>
<h2>
<a onClick={this.changeState.bind(this)}>Press Here!</a>
</h2>
</div>);
}

shouldComponentUpdate(nextProps, nextState)
{
console.log("shouldComponentUpdate()");
return true;
}

componentWillUpdate()
{
console.log("componentWillUpdate()");
}
componentDidUpdate()
{
console.log("componentDidUpdate()");
}
}
ReactDOM.render(
<Test />,
document.getElementById('root'));
Output:

JB PORTALS 32
FULL STACK DEVELOPMENT - WEEK 5
4. Error Handling
There are two main methods in error handling. These method are used in the error
boundary mechanism in React. We wrap the component (from where there is a
possibility of error occurrences ) in a class which handles the below methods.

 Static method getDerivedStateFromError(error)


 componentDidCatch(error,info)

Static getDerivedStateFromError(error): As name of the method suggest, we can


update state object here based on error received from descended component.

componentDidCatch(error, info): we can log the errors using api call. This is
helpful in displaying useful error message on screen instead of technical errors.

A class can be termed as an error boundary if it implements at least one


method from above two error handling lifecycle methods. Its main purpose is to
show a fallback ui once we get an error.

If error is not cached by error boundary class then the entire react component
tree below that component will be removed.
We can use the try catch in some methods but in application wide using error
boundary is better standard. It keeps the declarative nature of react intact.

Try it on CodePen: : https://codepen.io/gaearon/pen/xEmzGg?editors=0010

Handling Events
REFERENCE LINK: https://reactjs.org/docs/handling-events.html

Handling events with React elements is very similar to handling events on DOM
elements. There are some syntax differences:

 React events are named using camelCase, rather than lowercase.


 With JSX you pass a function as the event handler, rather than a string.

For example, the HTML:


<button onclick="activateLasers()">
Activate Lasers
</button>

is slightly different in React:


<button onClick={activateLasers}> Activate Lasers
</button>

JB PORTALS 33
FULL STACK DEVELOPMENT - WEEK 5
Another difference is that you cannot return false to prevent default behavior
in React. You must call preventDefault explicitly. For example, with plain HTML, to
prevent the default form behavior of submitting, you can write:

<form onsubmit="console.log('You clicked submit.'); return false">


<button type="submit">Submit</button>
</form>

In React, this could instead be:


function Form() {
function handleSubmit(e) {
e.preventDefault(); console.log('You clicked submit.');
}

return (
<form onSubmit={handleSubmit}>
<button type="submit">Submit</button>
</form>
);
}

Here, e is a synthetic event. React defines these synthetic events according to


the W3C spec, so you don’t need to worry about cross-browser compatibility. React
events do not work exactly the same as native events. See
the SyntheticEvent reference guide to learn more.

When using React, you generally don’t need to call addEventListener to add
listeners to a DOM element after it is created. Instead, just provide a listener when the
element is initially rendered.

When you define a component using an ES6 class, a common pattern is for an
event handler to be a method on the class. For example, this Toggle component
renders a button that lets the user toggle between “ON” and “OFF” states:

class Toggle extends React.Component {


constructor(props) {
super(props);
this.state = {isToggleOn: true};

// This binding is necessary to make `this` work in the callback


this.handleClick = this.handleClick.bind(this); }

handleClick() { this.setState(prevState => ({ isToggleOn:


!prevState.isToggleOn })); }
render() {
JB PORTALS 34
FULL STACK DEVELOPMENT - WEEK 5
return (
<button onClick={this.handleClick}> {this.state.isToggleOn ? 'ON' :
'OFF'}
</button>
);
}
}

You have to be careful about the meaning of this in JSX callbacks. In JavaScript,
class methods are not bound by default. If you forget to bind this.handleClick and pass
it to onClick, this will be undefined when the function is actually called. This is not
React-specific behavior; it is a part of how functions work in JavaScript. Generally, if
you refer to a method without () after it, such as onClick={this.handleClick}, you
should bind that method.

If calling bind annoys you, there are two ways you can get around this. You can
use public class fields syntax to correctly bind callbacks:

class LoggingButton extends React.Component {


// This syntax ensures `this` is bound within handleClick. handleClick = ()
=> { console.log('this is:', this); }; render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}

This syntax is enabled by default in Create React App. If you aren’t using class
fields syntax, you can use an arrow function in the callback:

class LoggingButton extends React.Component {


handleClick() {
console.log('this is:', this);
}

render() {
// This syntax ensures `this` is bound within handleClick return (
<button onClick={() => this.handleClick()}> Click me
</button>
);
}
}

JB PORTALS 35
FULL STACK DEVELOPMENT - WEEK 5
Passing Arguments to Event Handlers
Inside a loop, it is common to want to pass an extra parameter to an event
handler. For example, if id is the row ID, either of the following would work:

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>


<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

The above two lines are equivalent, and use arrow


functions and Function.prototype.bind respectively. In both cases, the e argument
representing the React event will be passed as a second argument after the ID. With
an arrow function, we have to pass it explicitly, but with bind any further arguments
are automatically forwarded.

Conditional Rendering
REFERENCE LINK: https://reactjs.org/docs/conditional-rendering.html

In React, you can create distinct components that encapsulate behavior you
need. Then, you can render only some of them, depending on the state of your
application.

Conditional rendering in React works the same way conditions work in


JavaScript. Use JavaScript operators like if or the conditional operator to create
elements representing the current state, and let React update the UI to match them.

Consider these two components:


function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}

We’ll create a Greeting component that displays either of these components


depending on whether a user is logged in:

function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) { return <UserGreeting />; } return <GuestGreeting />;}
const root = ReactDOM.createRoot(document.getElementById('root'));
// Try changing to isLoggedIn={true}:
root.render(<Greeting isLoggedIn={false} />);

JB PORTALS 36
FULL STACK DEVELOPMENT - WEEK 5
Element Variables
You can use variables to store elements. This can help you conditionally render
a part of the component while the rest of the output doesn’t change.Consider these
two new components representing Logout and Login buttons:

function LoginButton(props) {
return (
<button onClick={props.onClick}>
Login
</button>
);
}

function LogoutButton(props) {
return (
<button onClick={props.onClick}>
Logout
</button>
);
}

In the example below, we will create a stateful component called LoginControl.


It will render either <LoginButton /> or <LogoutButton /> depending on its current
state. It will also render a <Greeting /> from the previous example:

class LoginControl extends React.Component {


constructor(props) {
super(props);
this.handleLoginClick = this.handleLoginClick.bind(this);
this.handleLogoutClick = this.handleLogoutClick.bind(this);
this.state = {isLoggedIn: false};
}

handleLoginClick() {
this.setState({isLoggedIn: true});
}

handleLogoutClick() {
this.setState({isLoggedIn: false});
}

render() {
const isLoggedIn = this.state.isLoggedIn;
let button;

JB PORTALS 37
FULL STACK DEVELOPMENT - WEEK 5
if (isLoggedIn) { button = <LogoutButton
onClick={this.handleLogoutClick} />; } else { button = <LoginButton
onClick={this.handleLoginClick} />; }
return (
<div>
<Greeting isLoggedIn={isLoggedIn} /> {button} </div>
);
}
}

const root = ReactDOM.createRoot(document.getElementById('root'));


root.render(<LoginControl />);

While declaring a variable and using an if statement is a fine way to


conditionally render a component, sometimes you might want to use a shorter syntax.
There are a few ways to inline conditions in JSX, explained below.
Inline If with Logical && Operator

You may embed expressions in JSX by wrapping them in curly braces. This
includes the JavaScript logical && operator. It can be handy for conditionally
including an element:

function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 && <h2> You have
{unreadMessages.length} unread messages. </h2> } </div>
);
}

const messages = ['React', 'Re: React', 'Re:Re: React'];

const root = ReactDOM.createRoot(document.getElementById('root'));


root.render(<Mailbox unreadMessages={messages} />);

It works because in JavaScript, true && expression always evaluates


to expression, and false && expression always evaluates to false. Therefore, if the
condition is true, the element right after && will appear in the output. If it is false,
React will ignore and skip it.

JB PORTALS 38
FULL STACK DEVELOPMENT - WEEK 5
Note that returning a falsy expression will still cause the element after && to
be skipped but will return the falsy expression. In the example
below, <div>0</div> will be returned by the render method.

render() {
const count = 0; return (
<div>
{count && <h1>Messages: {count}</h1>} </div>
);
}

Inline If-Else with Conditional Operator


Another method for conditionally rendering elements inline is to use the
JavaScript conditional operator condition ? true : false. In the example below, we use
it to conditionally render a small block of text.

render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in. </div>
);
}

It can also be used for larger expressions although it is less obvious what’s
going on:
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? <LogoutButton onClick={this.handleLogoutClick} />
: <LoginButton onClick={this.handleLoginClick} /> }
</div> );
}

Just like in JavaScript, it is up to you to choose an appropriate style based on


what you and your team consider more readable. Also remember that whenever
conditions become too complex, it might be a good time to extract a component.

Preventing Component from Rendering


In rare cases you might want a component to hide itself even though it was
rendered by another component. To do this return null instead of its render output.

JB PORTALS 39
FULL STACK DEVELOPMENT - WEEK 5
In the example below, the <WarningBanner /> is rendered depending on the
value of the prop called warn. If the value of the prop is false, then the component
does not render:

function WarningBanner(props) {
if (!props.warn) { return null; }
return (
<div className="warning">
Warning!
</div>
);
}

class Page extends React.Component {


constructor(props) {
super(props);
this.state = {showWarning: true};
this.handleToggleClick = this.handleToggleClick.bind(this);
}

handleToggleClick() {
this.setState(state => ({
showWarning: !state.showWarning
}));
}

render() {
return (
<div>
<WarningBanner warn={this.state.showWarning} /> <button
onClick={this.handleToggleClick}>
{this.state.showWarning ? 'Hide' : 'Show'}
</button>
</div>
);
}
}

const root = ReactDOM.createRoot(document.getElementById('root'));


root.render(<Page />);

Returning null from a component’s render method does not affect the firing of
the component’s lifecycle methods. For instance componentDidUpdate will still be
called.
JB PORTALS 40
FULL STACK DEVELOPMENT - WEEK 5
Lists and Keys
REFERENCE LINK: https://reactjs.org/docs/lists-and-keys.html

First, let’s review how you transform lists in JavaScript.


Given the code below, we use the map() function to take an array of numbers and
double their values. We assign the new array returned by map() to the
variable doubled and log it:

const numbers = [1, 2, 3, 4, 5];


const doubled = numbers.map((number) => number * 2);console.log(doubled);

This code logs [2, 4, 6, 8, 10] to the console. In React, transforming arrays into lists
of elements is nearly identical.

Rendering Multiple Components


You can build collections of elements and include them in JSX using curly
braces {}. Below, we loop through the numbers array using the
JavaScript map() function. We return a <li> element for each item. Finally, we assign
the resulting array of elements to listItems:

const numbers = [1, 2, 3, 4, 5];


const listItems = numbers.map((number) => <li>{number}</li>);

Then, we can include the entire listItems array inside a <ul> element:

<ul>{listItems}</ul>

This code displays a bullet list of numbers between 1 and 5.

Basic List Component


Usually you would render lists inside a component. We can refactor the
previous example into a component that accepts an array of numbers and outputs a
list of elements.

function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) => <li>{number}</li> ); return
(
<ul>{listItems}</ul> );
}

const numbers = [1, 2, 3, 4, 5];


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<NumberList numbers={numbers} />);
JB PORTALS 41
FULL STACK DEVELOPMENT - WEEK 5
When you run this code, you’ll be given a warning that a key should be provided
for list items. A “key” is a special string attribute you need to include when creating
lists of elements. We’ll discuss why it’s important in the next section.

Let’s assign a key to our list items inside numbers.map() and fix the missing
key issue.

function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li key={number.toString()}> {number}
</li>
);
return (
<ul>{listItems}</ul>
);
}

Keys
Keys help React identify which items have changed, are added, or are removed.
Keys should be given to the elements inside the array to give the elements a stable
identity:

const numbers = [1, 2, 3, 4, 5];


const listItems = numbers.map((number) =>
<li key={number.toString()}> {number}
</li>
);

The best way to pick a key is to use a string that uniquely identifies a list item
among its siblings. Most often you would use IDs from your data as keys:

const todoItems = todos.map((todo) =>


<li key={todo.id}> {todo.text}
</li>
);

When you don’t have stable IDs for rendered items, you may use the item index
as a key as a last resort:

const todoItems = todos.map((todo, index) =>


// Only do this if items have no stable IDs <li key={index}> {todo.text}
</li>
);
JB PORTALS 42
FULL STACK DEVELOPMENT - WEEK 5
We don’t recommend using indexes for keys if the order of items may change.
This can negatively impact performance and may cause issues with component state.
Check out Robin Pokorny’s article for an in-depth explanation on the negative impacts
of using an index as a key. If you choose not to assign an explicit key to list items then
React will default to using indexes as keys.

Here is an in-depth explanation about why keys are necessary if you’re


interested in learning more.

Extracting Components with Keys


Keys only make sense in the context of the surrounding array. For example, if
you extract a ListItem component, you should keep the key on the <ListItem
/> elements in the array rather than on the <li> element in the ListItem itself.

Example: Incorrect Key Usage


function ListItem(props) {
const value = props.value;
return (
// Wrong! There is no need to specify the key here: <li
key={value.toString()}> {value}
</li>
);
}

function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
// Wrong! The key should have been specified here: <ListItem
value={number} /> );
return (
<ul>
{listItems}
</ul>
);
}

Example: Correct Key Usage

function ListItem(props) {
// Correct! There is no need to specify the key here: return
<li>{props.value}</li>;}

function NumberList(props) {
const numbers = props.numbers;

JB PORTALS 43
FULL STACK DEVELOPMENT - WEEK 5
const listItems = numbers.map((number) =>
// Correct! Key should be specified inside the array. <ListItem
key={number.toString()} value={number} /> );
return (
<ul>
{listItems}
</ul>
);
}

A good rule of thumb is that elements inside the map() call need keys. Keys
Must Only Be Unique Among Siblings. Keys used within arrays should be unique
among their siblings. However, they don’t need to be globally unique. We can use the
same keys when we produce two different arrays:

function Blog(props) {
const sidebar = ( <ul>
{props.posts.map((post) =>
<li key={post.id}> {post.title}
</li>
)}
</ul>
);
const content = props.posts.map((post) => <div key={post.id}>
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
);
return (
<div>
{sidebar} <hr />
{content} </div>
);
}

const posts = [
{id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
{id: 2, title: 'Installation', content: 'You can install React from npm.'}
];

const root = ReactDOM.createRoot(document.getElementById('root'));


root.render(<Blog posts={posts} />);

JB PORTALS 44
FULL STACK DEVELOPMENT - WEEK 5
Keys serve as a hint to React but they don’t get passed to your components. If
you need the same value in your component, pass it explicitly as a prop with a
different name:
const content = posts.map((post) =>
<Post
key={post.id} id={post.id} title={post.title} />
);

With the example above, the Post component can read props.id, but
not props.key.

Embedding map() in JSX


In the examples above we declared a separate listItems variable and included
it in JSX:

function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) => <ListItem
key={number.toString()} value={number} /> ); return (
<ul>
{listItems}
</ul>
);
}

JSX allows embedding any expression in curly braces so we could inline


the map() result:

function NumberList(props) {
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) => <ListItem key={number.toString()}
value={number} /> )} </ul>
);
}

Sometimes this results in clearer code, but this style can also be abused. Like
in JavaScript, it is up to you to decide whether it is worth extracting a variable for
readability. Keep in mind that if the map() body is too nested, it might be a good time
to extract a component.

JB PORTALS 45
FULL STACK DEVELOPMENT - WEEK 5
Forms
REFERENCE LINK: https://reactjs.org/docs/forms.html

HTML form elements work a bit differently from other DOM elements in React,
because form elements naturally keep some internal state. For example, this form in
plain HTML accepts a single name:

<form>
<label>
Name:
<input type="text" name="name" />
</label>
<input type="submit" value="Submit" />
</form>

This form has the default HTML form behavior of browsing to a new page when
the user submits the form. If you want this behavior in React, it just works. But in most
cases, it’s convenient to have a JavaScript function that handles the submission of the
form and has access to the data that the user entered into the form. The standard way
to achieve this is with a technique called “controlled components”.

Controlled Components
In HTML, form elements such as <input>, <textarea>, and <select> typically
maintain their own state and update it based on user input. In React, mutable state is
typically kept in the state property of components, and only updated with setState().

We can combine the two by making the React state be the “single source of
truth”. Then the React component that renders a form also controls what happens in
that form on subsequent user input. An input form element whose value is controlled
by React in this way is called a “controlled component”.

For example, if we want to make the previous example log the name when it is
submitted, we can write the form as a controlled component:

class NameForm extends React.Component {


constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}

handleChange(event) { this.setState({value: event.target.value}); }


handleSubmit(event) {
JB PORTALS 46
FULL STACK DEVELOPMENT - WEEK 5
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}

render() {
return (
<form onSubmit={this.handleSubmit}> <label>
Name:
<input type="text" value={this.state.value}
onChange={this.handleChange} /> </label>
<input type="submit" value="Submit" />
</form>
);
}
}

Since the value attribute is set on our form element, the displayed value will
always be this.state.value, making the React state the source of truth.
Since handleChange runs on every keystroke to update the React state, the displayed
value will update as the user types.

With a controlled component, the input’s value is always driven by the React
state. While this means you have to type a bit more code, you can now pass the value
to other UI elements too, or reset it from other event handlers.

The textarea Tag


In HTML, a <textarea> element defines its text by its children:

<textarea>
Hello there, this is some text in a text area
</textarea>

In React, a <textarea> uses a value attribute instead. This way, a form using
a <textarea> can be written very similarly to a form that uses a single-line input:

class EssayForm extends React.Component {


constructor(props) {
super(props);
this.state = { value: 'Please write an essay about your favorite DOM
element.' };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}

JB PORTALS 47
FULL STACK DEVELOPMENT - WEEK 5
handleChange(event) { this.setState({value: event.target.value}); }
handleSubmit(event) {
alert('An essay was submitted: ' + this.state.value);
event.preventDefault();
}

render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Essay:
<textarea value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}

Notice that this.state.value is initialized in the constructor, so that the text area
starts off with some text in it.

The select Tag


In HTML, <select> creates a drop-down list. For example, this HTML creates a
drop-down list of flavors:

<select>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option selected value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>

Note that the Coconut option is initially selected, because of


the selected attribute. React, instead of using this selected attribute, uses
a value attribute on the root select tag. This is more convenient in a controlled
component because you only need to update it in one place. For example

JB PORTALS 48
FULL STACK DEVELOPMENT - WEEK 5
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}

handleChange(event) { this.setState({value: event.target.value}); }


handleSubmit(event) {
alert('Your favorite flavor is: ' + this.state.value);
event.preventDefault();
}

render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<input type="submit" value="Submit" />
</form>
);
}
}

Overall, this makes it so that <input type="text">, <textarea>, and <select> all
work very similarly - they all accept a value attribute that you can use to implement
a controlled component.

Note
You can pass an array into the value attribute, allowing you to select multiple options
in a select tag:

<select multiple={true} value={['B', 'C']}>

JB PORTALS 49
FULL STACK DEVELOPMENT - WEEK 5
The file input Tag
In HTML, an <input type="file"> lets the user choose one or more files from
their device storage to be uploaded to a server or manipulated by JavaScript via
the File API.

<input type="file" />

Because its value is read-only, it is an uncontrolled component in React. It is


discussed together with other uncontrolled components later in the documentation.

Handling Multiple Inputs


When you need to handle multiple controlled input elements, you can add
a name attribute to each element and let the handler function choose what to do based
on the value of event.target.name.

For example:
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};

this.handleInputChange = this.handleInputChange.bind(this);
}

handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value });
}

render() {
return (
<form>
<label>
Is going:
<input
name="isGoing" type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
JB PORTALS 50
FULL STACK DEVELOPMENT - WEEK 5
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests" type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}

Note how we used the ES6 computed property name syntax to update the state
key corresponding to the given input name:

this.setState({
[name]: value});

It is equivalent to this ES5 code:

var partialState = {};


partialState[name] = value;this.setState(partialState);

Also, since setState() automatically merges a partial state into the current state,
we only needed to call it with the changed parts.

Uncontrolled Components
In most cases, we recommend using controlled components to implement
forms. In a controlled component, form data is handled by a React component. The
alternative is uncontrolled components, where form data is handled by the DOM
itself.

To write an uncontrolled component, instead of writing an event handler for


every state update, you can use a ref to get form values from the DOM. For example,
this code accepts a single name in an uncontrolled component:

class NameForm extends React.Component {


constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.input = React.createRef(); }

JB PORTALS 51
FULL STACK DEVELOPMENT - WEEK 5
handleSubmit(event) {
alert('A name was submitted: ' + this.input.current.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" ref={this.input} /> </label>
<input type="submit" value="Submit" />
</form>
);
}
}

Since an uncontrolled component keeps the source of truth in the DOM, it is


sometimes easier to integrate React and non-React code when using uncontrolled
components. It can also be slightly less code if you want to be quick and dirty.
Otherwise, you should usually use controlled components. If it’s still not clear which
type of component you should use for a particular situation, you might find this article
on controlled versus uncontrolled inputs to be helpful.

Default Values
In the React rendering lifecycle, the value attribute on form elements will
override the value in the DOM. With an uncontrolled component, you often want
React to specify the initial value, but leave subsequent updates uncontrolled. To
handle this case, you can specify a defaultValue attribute instead of value. Changing
the value of defaultValue attribute after a component has mounted will not cause any
update of the value in the DOM.

render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
defaultValue="Bob" type="text"
ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}

JB PORTALS 52
FULL STACK DEVELOPMENT - WEEK 5
Likewise,
<input type="checkbox"> and <input type="radio"> support defaultChecked,
and <select> and <textarea> supports defaultValue.

The file input Tag


In HTML, an <input type="file"> lets the user choose one or more files from
their device storage to be uploaded to a server or manipulated by JavaScript via
the File API.
<input type=”file” />

In React, an <input type="file" /> is always an uncontrolled component


because its value can only be set by a user, and not programmatically. You should use
the File API to interact with the files. The following example shows how to create a ref
to the DOM node to access file(s) in a submit handler:

class FileInput extends React.Component {


constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.fileInput = React.createRef(); }
handleSubmit(event) {
event.preventDefault();
alert(
`Selected file - ${this.fileInput.current.files[0].name}` );
}

render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Upload file:
<input type="file" ref={this.fileInput} /> </label>
<br />
<button type="submit">Submit</button>
</form>
);
}
}

const root = ReactDOM.createRoot(


document.getElementById('root')
);
root.render(<FileInput />);

JB PORTALS 53
FULL STACK DEVELOPMENT - WEEK 5
Lifting State up in ReactJS
REFERENCE LINK: https://reactjs.org/docs/lifting-state-up.html

https://www.geeksforgeeks.org/lifting-state-up-in-reactjs/

Lifting up the State: As we know, every component in React has its own state.
Because of this sometimes data can be redundant and inconsistent. So, by Lifting up
the state we make the state of the parent component as a single source of truth and
pass the data of the parent in its children.

Time to use Lift up the State: If the data in “parent and children components” or
in “cousin components” is Not in Sync.

Example 1: If we have 2 components in our App. A -> B where, A is parent of B.


keeping the same data in both Component A and B might cause inconsistency of
data.

Example 2: If we have 3 components in our App.


A
/\
B C
Where A is the parent of B and C. In this case, If there is some Data only in
component B but, component C also wants that data. We know Component C cannot
access the data because a component can talk only to its parent or child (Not
cousins).

Problem: Let’s Implement this with a simple but general example. We are
considering the second example.
Complete File Structure:

JB PORTALS 54
FULL STACK DEVELOPMENT - WEEK 5
We will store the current input’s temperature and scale in its local state. This
is the state we “lifted up” from the inputs, and it will serve as the “source of truth” for
both of them. It is the minimal representation of all the data we need to know in order
to render both inputs.

For example, if we enter 37 into the Celsius input, the state of


the Calculator component will be:

{
temperature: '37',
scale: 'c'
}

If we later edit the Fahrenheit field to be 212, the state of the Calculator will be:
{
temperature: '212',
scale: 'f'
}

const scaleNames = {
c: 'Celsius',
f: 'Fahrenheit'
};

function toCelsius(fahrenheit) {
return (fahrenheit - 32) * 5 / 9;
}

function toFahrenheit(celsius) {
return (celsius * 9 / 5) + 32;
}

function tryConvert(temperature, convert) {


const input = parseFloat(temperature);
if (Number.isNaN(input)) {
return '';
}
const output = convert(input);
const rounded = Math.round(output * 1000) / 1000;
return rounded.toString();
}

JB PORTALS 55
FULL STACK DEVELOPMENT - WEEK 5

function BoilingVerdict(props) {
if (props.celsius >= 100) {
return <p>The water would boil.</p>;
}
return <p>The water would not boil.</p>;
}

class TemperatureInput extends React.Component {


constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}

handleChange(e) {
this.props.onTemperatureChange(e.target.value);
}

render() {
const temperature = this.props.temperature;
const scale = this.props.scale;
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={temperature}
onChange={this.handleChange} />
</fieldset>
);
}
}

class Calculator extends React.Component {


constructor(props) {
super(props);
this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
this.state = {temperature: '', scale: 'c'};
}

JB PORTALS 56
FULL STACK DEVELOPMENT - WEEK 5
handleCelsiusChange(temperature) {
this.setState({scale: 'c', temperature});
}

handleFahrenheitChange(temperature) {
this.setState({scale: 'f', temperature});
}

render() {
const scale = this.state.scale;
const temperature = this.state.temperature;
const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) :
temperature;
const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) :
temperature;

return (
<div>
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={this.handleCelsiusChange} />
<TemperatureInput
scale="f"
temperature={fahrenheit}
onTemperatureChange={this.handleFahrenheitChange} />
<BoilingVerdict
celsius={parseFloat(celsius)} />
</div>
);
}
}

const root = ReactDOM.createRoot(document.getElementById('root'));


root.render(<Calculator />);

JB PORTALS 57
FULL STACK DEVELOPMENT - WEEK 5
Testing Single Page Applications
REFERENCE LINK: https://medium.com/inspiredbrilliance/testing-single-page-
applications-b4001adc6452

There are many ways to test the frontend of a web application. Most widely
used methods are to test the application as a user using Selenium Web-driver or
similar libraries. This means that you have to write tests for each and every scenario
as a user workflow.

This made our testing slow and delayed the whole Test Driven Development
cycle. That leads to most UI developers to only write application code and let the UI
Automation teams write tests for them. It is not difficult to see then that the
dependency on multiple teams delayed the feedback cycle. Thus delaying the
continuous delivery process.
But today we are mainly going to focus on testing Single Page Applications
(SPA). Modern SPA frameworks like React, Angular and Vue.js use component based
approach to build UI by composing smaller components together. This provides us an
opportunity to test our application logic at component level as well as the complete
app as a black box.
Because of this granularity of modern SPA testing our testing pyramid would
usually look like following:

Let’s look at each one of them from bottom to top.

JB PORTALS 58
FULL STACK DEVELOPMENT - WEEK 5
1. Unit Tests:
These are your tests for plain old Javascript functions and classes that you are
writing as part of the application. These may include any domain classes, functional
utilities or more specifically the helper functions of the UI components. Because these
tests usually don’t depend on any other code or library you should be able to write
tests for each and every use case of these functions. There are many frameworks
available in Javascript to test this kind of Javascript objects. Most commonly used
are Jasmine, Mocha and Jest.

2. Single Component Tests:


By definition UI components are supposed to be individual building blocks of
your applications. These should encapsulate all the logic necessary to render and
behave in isolation of other components. If you are writing Pure components, that
means that their behaviour is predication and depends only on the properties passed
to them, then we can render that component in our test environment without the
boilerplate code of the rest of the application. Then we can test all kinds of use cases
by changing the properties of this component.
You can use the testing frameworks Testing Library or Enzyme which work
with react-dom to test individual components.

3. Component Integration Tests


After we test each component in isolation it is time to check if components are
being used properly in the context of another component. In the previous step we
were rendering and testing only one component, but if we want to make sure that
component is passing correct data to the child component and handling events raised
by children then we must render our component with all its children without mocking
them. This may seem that we are now dependent on the child components but that’s
precisely what we want to test. This kind of test helps us find any integration issues
between dependent components.

4. End to End Tests:

After testing all our components in isolation of groups we still need to make
sure that our app works end to end without stubbing any of its components. The goal
of end to end (e2e) tests is to test our app as a user. We can not assume any internals
of the applications. We should treat it as a complete black box and assert the behaviour
completely on the outcome of user actions.
There are many ways to execute e2e tests in browser, for example
using Selenium Web Driver, Puppeteer, TestCafe or Cypress

JB PORTALS 59

You might also like