0% found this document useful (0 votes)
19 views61 pages

Module 6

Uploaded by

snehalparab183
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views61 pages

Module 6

Uploaded by

snehalparab183
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 61

Module 06

Advance React
Functional components
React Refs
• Refs is the shorthand used for references in React.
• It is similar to keys in React.
• It is an attribute which makes it possible to store a reference to particular DOM nodes
or React elements.
• It provides a way to access React DOM nodes or React elements and how to interact
with it.
• It is used when we want to change the value of a child component, without making the
use of props.

When to Use Refs


Refs can be used in the following cases:
• When we need DOM measurements such as managing focus, text selection, or media
playback.
• It is used in triggering imperative animations.
• When integrating with third-party DOM libraries.
• It can also use as in callbacks.
How to create Refs

• In React, Refs can be created by using React.createRef().


• It can be assigned to React elements via the ref attribute.
• It is commonly assigned to an instance property when a component is created, and
then can be referenced throughout the component.

class MyComponent extends React.Component {


constructor(props) {
super(props);
this.callRef = React.createRef();
}
render() {
return <div ref={this.callRef} />;
}
}
How to access Refs

In React, when a ref is passed to an element inside render method, a reference to the
node can be accessed via the current attribute of the ref.

const node = this.callRef.current;


bind()
The bind() is an inbuilt method in React that is used to pass the data as an argument
to the function of a class based component.

focus()
focus() method tells the browser which element is being acted on
Add Ref to DOM elements
In the below example, we are adding a ref to store the
reference to a DOM node or element.
render() {
return (
import React, { Component } from 'react';
<div>
import { render } from 'react-dom';
<h2>Adding Ref to DOM element</h2>
<input
class App extends React.Component {
type="text"
constructor(props) {
ref={this.callRef} />
super(props);
<input
this.callRef = React.createRef();
type="button"
this.addingRefInput =
value="Add text input"
this.addingRefInput.bind(this);
onClick={this.addingRefInput}
}
/>
</div>
addingRefInput() {
);
this.callRef.current.focus();
}
}
}
export default App;
Add Ref to Class components
In the below example, we are adding a ref to store
the reference to a class component.
Example
import React, { Component } from 'react'; class App extends React.Component {
import { render } from 'react-dom'; constructor(props) {
super(props);
function CustomInput(props) { this.callRefInput = React.createRef();
let callRefInput = React.createRef(); }

function handleClick() { focusRefInput() {


callRefInput.current.focus(); this.callRefInput.current.focus();
} }
return (
<div> render() {
<h2>Adding Ref to Class Component</h2> return (
<input <CustomInput ref={this.callRefInput} />
type="text" );
ref={callRefInput} /> }
<input type="button" }
value="Focus input" export default App;
onClick={handleClick} />
</div>
); }
Output:
Callback refs
• In react, there is another way to use refs that is called "callback refs" and it gives more
control when the refs are set and unset.
• Instead of creating refs by createRef() method, React allows a way to create refs by
passing a callback function to the ref attribute of a component.
• It looks like the below code.

<input type="text" ref={element => this.callRefInput = element} />

The callback function is used to store a reference to the DOM node in an instance
property and can be accessed elsewhere. It can be accessed as below:

this.callRefInput.value
Hooks
React Hooks
• Hooks are the new feature introduced in the React 16.8 version.
• It allows you to use state and other React features without writing a class.
• Hooks are the functions which "hook into" React state and lifecycle features from
function components.
• It does not work inside classes.
• Hooks are backward-compatible, which means it does not contain any breaking
changes.
• Also, it does not replace your knowledge of React concepts.

When to use a Hooks

• If you write a function component, and then you want to add some state to it,
previously you do this by converting it to a class.
• But, now you can do it by using a Hook inside the existing function component.
Rules of Hooks
Hooks are similar to JavaScript functions, but you need to follow these two rules when
using them. Hooks rule ensures that all the stateful logic in a component is visible in its
source code. These rules are:

1. Only call Hooks at the top level


Do not call Hooks inside loops, conditions, or nested functions. Hooks should always be
used at the top level of the React functions. This rule ensures that Hooks are called in
the same order each time a components renders.

2. Only call Hooks from React functions


You cannot call Hooks from regular JavaScript functions. Instead, you can call Hooks
from React function components. Hooks can also be called from custom Hooks.
Pre-requisites for React Hooks

• Node version 6 or above


• NPM version 5.2 or above
• Create-react-app tool for running the React App

React Hooks Installation


To use React Hooks, we need to run the following commands:

$ npm install [email protected] --save


$ npm install [email protected] --save

The above command will install the latest React and React-DOM alpha versions which
support React Hooks.
Hooks State
Hook state is the new way of declaring a state in React app. Hook uses useState() functional
component for setting and retrieving state. Let us understand Hook state with the following
example.

App.js

import React, { useState } from 'react';

function CountApp() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
export default CountApp;
output:
Hooks Effect

• The Effect Hook allows us to perform side effects (an action) in the function
components.
• It does not use components lifecycle methods which are available in class components.
• In other words, Effects Hooks are equivalent to componentDidMount(),
componentDidUpdate(), and componentWillUnmount() lifecycle methods.

Side effects have common features which the most web applications need to perform,
such as:

• Updating the DOM,


• Fetching and consuming data from a server API,
• Setting up a subscription, etc.
Let us understand Hook Effect with the following example.

import React, { useState, useEffect } from 'react';

function CounterExample() {
const [count, setCount] = useState(0);

// Similar to componentDidMount and componentDidUpdate:


useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
); }
export default CounterExample;

The above code is based on the previous example with a new feature which we set the
document title to a custom message, including the number of clicks.
In React component, there are two types of side effects:

1. Effects Without Cleanup


2. Effects With Cleanup

Effects without Cleanup


• It is used in useEffect which does not block the browser from updating the screen.
• It makes the app more responsive.
• The most common example of effects which don't require a cleanup are manual DOM
mutations, Network requests, Logging, etc.

Effects with Cleanup


• Some effects require cleanup after DOM updation.
• For example, if we want to set up a subscription to some external data source, it is
important to clean up memory so that we don't introduce a memory leak.
• React performs the cleanup of memory when the component unmounts.
• However, as we know that, effects run for every render method and not just once.
• Therefore, React also cleans up effects from the previous render before running the
effects next time.
Built-in Hooks
Here, we describe the APIs for the built-in Hooks in React. The built-in Hooks can be
divided into two parts, which are given below.

Basic Hooks

• useState
• useEffect
• useContext

Additional Hooks

• useReducer
• useCallback
• useMemo
• useRef
• useImperativeHandle
• useLayoutEffect
• useDebugValue
React useEffect Hooks
• The useEffect Hook allows you to perform side effects in your components.

• Some examples of side effects are: fetching data, directly updating the DOM,
and timers.

• useEffect accepts two arguments. The second argument is optional.

useEffect(<function>, <dependency>)
Let's use a timer as an example.

Example:
Use setTimeout() to count 1 second after initial render:

import { useState, useEffect } from "react";


import ReactDOM from "react-dom/client";

function Timer() {
const [count, setCount] = useState(0);

useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
});

return <h1>I've rendered {count} times!</h1>;


}

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


root.render(<Timer />);
• But wait!! It keeps counting even though it should only count once!

• useEffect runs on every render. That means that when the count changes, a render
happens, which then triggers another effect.

• This is not what we want. There are several ways to control when side effects run.

• We should always include the second parameter which accepts an array. We can
optionally pass dependencies to useEffect in this array.

1. No dependency passed:
useEffect(() => {
//Runs on every render
});

2. An empty array:
useEffect(() => { //Runs only on the first render }, []);

3. Props or state values:


useEffect(() => { //Runs on the first render //And any time any dependency value changes
}, [prop, state]);
Example:
Only run the effect on the initial render:

import { useState, useEffect } from "react";


import ReactDOM from "react-dom/client";

function Timer() {
const [count, setCount] = useState(0);

useEffect(() => {
setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
}, []); // <- add empty brackets here

return <h1>I've rendered {count} times!</h1>;


}

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


root.render(<Timer />);
Example: Here is an example of a useEffect Hook that is dependent on a variable. If the
count variable updates, the effect will run again:

import { useState, useEffect } from "react";


import ReactDOM from "react-dom/client";

function Counter() {
const [count, setCount] = useState(0);
const [calculation, setCalculation] = useState(0);

useEffect(() => {
setCalculation(() => count * 2);
}, [count]); // <- add the count variable here
return (
<>
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>+</button>
<p>Calculation: {calculation}</p>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Counter />);
Effect Cleanup
• Some effects require cleanup to reduce memory leaks.
• Timeouts, subscriptions, event listeners, and other effects that are no longer needed
should be disposed.
• We do this by including a return function at the end of the useEffect Hook.

Example:
Clean up the timer at the end of the useEffect Hook:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";
function Timer() {
const [count, setCount] = useState(0);

useEffect(() => {
let timer = setTimeout(() => {
setCount((count) => count + 1);
}, 1000);
return () => clearTimeout(timer)
}, []);
return <h1>I've rendered {count} times!</h1>;}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Timer />);
React Flux Concept
• Flux is an application architecture that Facebook uses internally for building the client-
side web application with React.
• It is not a library nor a framework.
• It is a kind of architecture that complements React as view and follows the concept of
Unidirectional Data Flow model.
• It is useful when the project has dynamic data, and we need to keep the data updated
in an effective manner.
• It reduces the runtime errors.

Flux applications have three major roles in dealing with data:

• Dispatcher
• Stores
• Views (React components)
Structure and Data Flow
• In Flux application, data flows in a single direction(unidirectional).
• This data flow is central to the flux pattern.
• The dispatcher, stores, and views are independent nodes with inputs and outputs.
• The actions are simple objects that contain new data and type property.
• Now, let us look at the various components of flux architecture one by one.

Dispatcher
• It is a central hub for the React Flux application and manages all data flow of your Flux
application.
• It is a registry of callbacks into the stores.
• It has no real intelligence of its own, and simply acts as a mechanism for distributing
the actions to the stores.
• All stores register itself and provide a callback.
• It is a place which handled all events that modify the store.
• When an action creator provides a new action to the dispatcher, all stores receive that
action via the callbacks in the registry.
The dispatcher's API has five methods. These are:

SN Methods Descriptions

1. register() It is used to register a store's action


handler callback.

2. unregister() It is used to unregisters a store's


callback.

3. waitFor() It is used to wait for the specified


callback to run first.

4. dispatch() It is used to dispatches an action.

5. isDispatching() It is used to checks if the dispatcher


is currently dispatching an action.
Stores
• It primarily contains the application state and logic.
• It is similar to the model in a traditional MVC.
• It is used for maintaining a particular state within the application, updates
themselves in response to an action, and emit the change event to alert the
controller view.

Views
• It is also called as controller-views.
• It is located at the top of the chain to store the logic to generate actions and receive
new data from the store.
• It is a React component listen to change events and receives the data from the stores
and re-render the application.
Actions
• The dispatcher method allows us to trigger a dispatch to the store and include a
payload of data, which we call an action.
• It is an action creator or helper methods that pass the data to the dispatcher.

Advantage of Flux
• It is a unidirectional data flow model which is easy to understand.
• It is open source and more of a design pattern than a formal framework like MVC
architecture.
• The flux application is easier to maintain.
• The flux application parts are decoupled.
Model View Controller framework
• MVC stands for Model View Controller.
• It is an architectural pattern used for developing the user interface.
• It divides the application into three different logical components: the Model, the View,
and the Controller.
• It is first introduced in 1976 in the Smalltalk programming language.
• In MVC, each component is built to handle specific development aspect of an application.
• It is one of the most used web development frameworks to create scalable projects.
MVC Architecture
The MVC architecture contains the three components. These are:

• Model: It is responsible for maintaining the behavior and data of an application.

• View: It is used to display the model in the user interface.

• Controller: It acts as an interface between the Model and the View components. It
takes user input, manipulates the data(model) and causes the view to update.
SN MVC FLUX
1. It was introduced in 1976. It was introduced just a few years ago.

2. It supports Bi-directional data Flow model. It supports Uni-directional data flow model.

3. In this, data binding is the key. In this, events or actions are the keys.

4. It is synchronous. It is asynchronous.
5. Here, controllers handle everything(logic). Here, stores handle all logic.

6. It is hard to debug. It is easy to debug because it has common initiating point: Dispatcher.

7. It is difficult to understand as the project size increases. It is easy to understand.

8. Its maintainability is difficult as the project scope goes Its maintainability is easy and reduces runtime errors.
huge.

9. Testing of application is difficult. Testing of application is easy.

10. Scalability is complex. It can be easily scalable.


Bundling the application
• The React app bundled their files using tools like Webpack or Browserfy.
• Bundling is a process which takes multiple files and merges them into a single file,
which is called a bundle.
• The bundle is responsible for loading an entire app at once on the webpage.

We can understand it from the below example.

App.js

import { add } from './math.js';

console.log(add(16, 26)); // 42

math.js

export function add(a, b) {


return a + b;
}
Bundle file as like below:

function add(a, b) {
return a + b;
}

console.log(add(16, 26)); // 42

• As our app grows, our bundle will grow too, especially when we are using large third-
party libraries.
• If the bundle size gets large, it takes a long time to load on a webpage.
• For avoiding the large bundling, its good to start splitting your bundle.
• React 16.6.0, released in October 2018, and introduced a way of performing code
splitting.
• Code-Splitting is a feature supported by Webpack and Browserify, which can create
multiple bundles that can be dynamically loaded at runtime.

Code splitting uses React.lazy and Suspense tool/library, which helps you to load a
dependency lazily and only load it when needed by the user.

The code splitting improves:

o The performance of the app


o The impact on memory
o The downloaded Kilobytes (or Megabytes) size
React.lazy
• The best way for code splitting into the app is through the dynamic import() syntax.
• The React.lazy function allows us to render a dynamic import as a regular component.

Before
import ExampleComponent from './ExampleComponent';

function MyComponent() {
return (
<div>
<ExampleComponent />
</div>
);
}

After
const ExampleComponent = React.lazy(() => import('./ExampleComponent'));
function MyComponent() {
return (
<div>
<ExampleComponent />
</div>
); The above code snippet automatically loads the bundle which contains the
} ExampleComponent when the ExampleComponent gets rendered.
Suspense
• If the module which contains the ExampleComponent is not yet loaded by the
function component(MyComponent), then we need to show some fallback content
while we are waiting for it to load.

• We can do this using the suspense component.

• In other words, the suspense component is responsible for handling the output when
the lazy component is fetched and rendered.
const ExampleComponent = React.lazy(() => import('./ ExampleComponent'));

function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<ExampleComponent />
</Suspense>
</div>
);
}

• The fallback prop accepts the React elements which you want to render while waiting for
the component to load.
• We can combine multiple lazy components with a single Suspense component.
• It can be seen in the next example.
const ExampleComponent = React.lazy(() => import('./ ExampleComponent'));
const ExamComponent = React.lazy(() => import('./ ExamComponent'));

function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<section>
<ExampleComponent />
<ExamComponent />
</section>
</Suspense>
</div>
);
}
Error boundaries

• If any module fails to load, for example, due to network failure, we will get an error.
• We can handle these errors with Error Boundaries.
• Once we have created the Error Boundary, we can use it anywhere above our lazy
components to display an error state.

import MyErrorBoundary from './MyErrorBoundary';


const ExampleComponent = React.lazy(() => import('./ ExampleComponent'));
const ExamComponent = React.lazy(() => import('./ ExamComponent'));

const MyComponent = () => (


<div>
<MyErrorBoundary>
<Suspense fallback={<div>Loading...</div>}>
<section>
<ExampleComponent />
<ExamComponent />
</section>
</Suspense>
</MyErrorBoundary>
</div>
);
Route-based code splitting

• It is very tricky to decide where we introduce code splitting in the app.


• For this, we have to make sure that we choose the place which will split the bundles
evenly without disrupting the user experience.

• The route is the best place to start the code splitting.


• Route based code splitting is essential during the page transitions on the web, which takes
some amount of time to load.
• Here is an example of how to setup route-based code splitting into the app using React
Router with React.lazy.
import { Switch, BrowserRouter as Router, Route} from 'react-router-dom';
import React, { Suspense, lazy } from 'react';

const Home = lazy(() => import('./routes/Home'));


const About = lazy(() => import('./routes/About'));
const Contact = lazy(() => import('./routes/Contact'));

const App = () => (


<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/contact" component={Contact}/>
</Switch>
</Suspense>
</Router>
);
Named Export

• Currently, React.lazy supports default exports only.


• If any module you want to import using named exports, you need to create an
intermediate module that re-exports it as the default.
• We can understand it from the below example.

ExampleComponents.js

export const MyFirstComponent = /* ... */;


export const MySecondComponent = /* ... */;

MyFirstComponent.js

export { MyFirstComponent as default } from "./ExampleComponents.js";

MyApp.js

import React, { lazy } from 'react';


const MyFirstComponent = lazy(() => import("./MyFirstComponent.js"));
Web Pack
• webpack is a powerful module bundler and it becomes an essential part of our
JavaScript Ecosystem.

• Webpack is a free and open-source module bundler for JavaScript.

• It is made primarily for JavaScript, but it can transform front-end assets such as HTML,
CSS, and images if the corresponding loaders are included.

• Webpack takes modules with dependencies and generates static assets representing
those modules.
Module Bundler:

• Webpack, a simple but awesome module bundler.


• Module bundlers are just what they are called, they bundle up JavaScript modules
into one file.
• This way, when the client makes a request to your server, it doesn’t have to make
multiple requests for static files.
• Instead, one file is requested, which in some cases, includes your JavaScript bundle
and CSS style.
• This helps optimize load time and makes you more in control as you can choose to
include only what you need when you need it.

A Task Runner:

• The WebPack Task Runner automatically triggers when it


finds WebPack configuration files.

You might also like