0% found this document useful (0 votes)
278 views

React Hooks

Hooks are functions that allow you to "hook into" React state and lifecycle features from function components. The useState hook allows function components to have local state by taking the initial state value and returning a pair of values - the current state and a function to update it. The useEffect hook allows function components to perform side effects like data fetching or DOM manipulation. Custom hooks let you extract component logic into reusable functions.

Uploaded by

kirti Patel
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
278 views

React Hooks

Hooks are functions that allow you to "hook into" React state and lifecycle features from function components. The useState hook allows function components to have local state by taking the initial state value and returning a pair of values - the current state and a function to update it. The useEffect hook allows function components to perform side effects like data fetching or DOM manipulation. Custom hooks let you extract component logic into reusable functions.

Uploaded by

kirti Patel
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 110

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

1. Node version 6 or above


2. NPM version 5.2 or above
3. Create-react-app tool for running the React App

AD

React Hooks Installation

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


1. $ npm install [email protected] --save  
2. $ npm install [email protected] --save  

The above command will install the latest React and React-DOM alpha
versions which support React Hooks. Make sure the package.json file
lists the React and React-DOM dependencies as given below.

1. "react": "^16.8.0-alpha.1",  
2. "react-dom": "^16.8.0-alpha.1",  

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

1. import React, { useState } from 'react';  
2.   
3. function CountApp() {  
4.   // Declare a new state variable, which we'll call "count"  
5.   const [count, setCount] = useState(0);  
6.   
7.   return (  
8.     <div>  
9.       <p>You clicked {count} times</p>  
10.      <button onClick={() => setCount(count + 1)}>  
11.        Click me  
12.      </button>  
13.    </div>  
14.  );  
15.}  
16.export default CountApp;  

output:

In the above example, useState is the Hook which needs to call inside a
function component to add some local state to it. The useState returns a
pair where the first element is the current state value/initial value, and
the second one is a function which allows us to update it. After that, we
will call this function from an event handler or somewhere else. The
useState is similar to this.setState in class. The equivalent code without
Hooks looks like as below.

App.js

1. import React, { useState } from 'react';  
2.   
3. class CountApp extends React.Component {  
4.   constructor(props) {  
5.     super(props);  
6.     this.state = {  
7.       count: 0  
8.     };  
9.   }  
10.  render() {  
11.    return (  
12.      <div>  
13.        <p><b>You clicked {this.state.count} times</b></p>  
14.        <button onClick={() => this.setState({ count: this.state.count + 1 }
)}>  
15.          Click me  
16.        </button>  
17.      </div>  
18.    );  
19.  }  
20.}  
21.export default CountApp;  

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:

o Updating the DOM,


o Fetching and consuming data from a server API,
o 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.

Output:

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.

Custom Hooks

A custom Hook is a JavaScript function. The name of custom Hook


starts with "use" which can call other Hooks. A custom Hook is just like
a regular function, and the word "use" in the beginning tells that this
function follows the rules of Hooks. Building custom Hooks allows you
to extract component logic into reusable functions.

AD

Let us understand how custom Hooks works in the following example.

1. import React, { useState, useEffect } from 'react';  
2.   
3. const useDocumentTitle = title => {  
4.   useEffect(() => {  
5.     document.title = title;  
6.   }, [title])  
7. }  
8.   
9. function CustomCounter() {  
10.  const [count, setCount] = useState(0);  
11.  const incrementCount = () => setCount(count + 1);  
12.  useDocumentTitle(`You clicked ${count} times`);  
13.  // useEffect(() => {  
14.  //   document.title = `You clicked ${count} times`  
15.  // });  
16.  
17.  return (  
18.    <div>  
19.      <p>You clicked {count} times</p>  
20.      <button onClick={incrementCount}>Click me</button>  
21.    </div>  
22.  )  
23.}  
24.export default CustomCounter;  

In the above snippet, useDocumentTitle is a custom Hook which takes


an argument as a string of text which is a title. Inside this Hook, we call
useEffect Hook and set the title as long as the title has changed. The
second argument will perform that check and update the title only when
its local state is different than what we are passing in.

Note: A custom Hook is a convention which naturally follows from the


design of Hooks, instead of a React feature.

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

o useState
o useEffect
o useContext

AD

Additional Hooks

o useReducer
o useCallback
o useMemo
o useRef
o useImperativeHandle
o useLayoutEffect
o useDebugValue
React useState Hook

❮ PreviousNext ❯

The React useState Hook allows us to track state in a function


component.

State generally refers to data or properties that need to be tracking in an


application.

Import useState

To use the useState Hook, we first need to import it into our component.

Example:

At the top of your component, import the useState Hook.

import { useState } from "react";

Notice that we are destructuring useState from react as it is a named


export.

To learn more about destructuring, check out the ES6 section.

Initialize useState

We initialize our state by calling useState in our function component.

useState accepts an initial state and returns two values:

 The current state.


 A function that updates the state.

Example:

Initialize state at the top of the function component.


import { useState } from "react";

function FavoriteColor() {

const [color, setColor] = useState("");

Notice that again, we are destructuring the returned values


from useState.

The first value, color, is our current state.

The second value, setColor, is the function that is used to update our


state.

These names are variables that can be named anything you would like.

Lastly, we set the initial state to an empty string: useState("")

Read State

We can now include our state anywhere in our component.

Example:

Use the state variable in the rendered component.

import { useState } from "react";

import ReactDOM from "react-dom/client";

function FavoriteColor() {

const [color, setColor] = useState("red");

return <h1>My favorite color is {color}!</h1>

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


root.render(<FavoriteColor />);

Run Example »

Update State

To update our state, we use our state updater function.

We should never directly update state. Ex: color = "red" is not allowed.

Example:

Use a button to update the state:

import { useState } from "react";

import ReactDOM from "react-dom/client";

function FavoriteColor() {

const [color, setColor] = useState("red");

return (

<>

<h1>My favorite color is {color}!</h1>

<button

type="button"

onClick={() => setColor("blue")}

>Blue</button>

</>

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

root.render(<FavoriteColor />);
Run Example »

What Can State Hold

The useState Hook can be used to keep track of strings, numbers,


booleans, arrays, objects, and any combination of these!

We could create multiple state Hooks to track individual values.

Example:

Create multiple state Hooks:

import { useState } from "react";

import ReactDOM from "react-dom/client";

function Car() {

const [brand, setBrand] = useState("Ford");

const [model, setModel] = useState("Mustang");

const [year, setYear] = useState("1964");

const [color, setColor] = useState("red");

return (

<>

<h1>My {brand}</h1>

<p>

It is a {color} {model} from {year}.

</p>

</>

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

root.render(<Car />);

Run Example »

Or, we can just use one state and include an object instead!

Example:

Create a single Hook that holds an object:

import { useState } from "react";

import ReactDOM from "react-dom/client";

function Car() {

const [car, setCar] = useState({

brand: "Ford",

model: "Mustang",

year: "1964",

color: "red"

});

return (

<>

<h1>My {car.brand}</h1>

<p>

It is a {car.color} {car.model} from {car.year}.

</p>

</>

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

root.render(<Car />);

Run Example »

Since we are now tracking a single object, we need to reference that


object and then the property of that object when rendering the
component. (Ex: car.brand)

Updating Objects and Arrays in State

When state is updated, the entire state gets overwritten.

What if we only want to update the color of our car?

If we only called setCar({color: "blue"}), this would remove the brand,


model, and year from our state.

We can use the JavaScript spread operator to help us.

Example:

Use the JavaScript spread operator to update only the color of the car:

import { useState } from "react";

import ReactDOM from "react-dom/client";

function Car() {

const [car, setCar] = useState({

brand: "Ford",

model: "Mustang",

year: "1964",

color: "red"

});

const updateColor = () => {

setCar(previousState => {
return { ...previousState, color: "blue" }

});

return (

<>

<h1>My {car.brand}</h1>

<p>

It is a {car.color} {car.model} from {car.year}.

</p>

<button

type="button"

onClick={updateColor}

>Blue</button>

</>

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

root.render(<Car />);

Run Example »

Because we need the current value of state, we pass a function into


our setCar function. This function receives the previous value.

We then return an object, spreading the previousState and overwriting


only the color.

React useEffect Hooks

❮ PreviousNext ❯
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 />);

Run Example »

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]);

So, to fix this issue, let's only run this effect on the initial render.

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 />);

Run Example »

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 />);

Run Example »

If there are multiple dependencies, they should be included in


the useEffect dependency array.

w3schoolsCERTIFIED.2022

Get Certified!

Complete the React modules, do the exercises, take the exam and
become w3schools certified!!

$95 ENROLL

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 />);

Run Example »

Note: To clear the timer, we had to name it.

React useContext Hook

❮ PreviousNext ❯
React Context

React Context is a way to manage state globally.

It can be used together with the useState Hook to share state between


deeply nested components more easily than with useState alone.

The Problem

State should be held by the highest parent component in the stack that
requires access to the state.

To illustrate, we have many nested components. The component at the


top and bottom of the stack need access to the state.

To do this without Context, we will need to pass the state as "props"


through each nested component. This is called "prop drilling".

Example:

Passing "props" through nested components:

import { useState } from "react";

import ReactDOM from "react-dom/client";

function Component1() {

const [user, setUser] = useState("Jesse Hall");

return (

<>

<h1>{`Hello ${user}!`}</h1>

<Component2 user={user} />

</>

);

}
function Component2({ user }) {

return (

<>

<h1>Component 2</h1>

<Component3 user={user} />

</>

);

function Component3({ user }) {

return (

<>

<h1>Component 3</h1>

<Component4 user={user} />

</>

);

function Component4({ user }) {

return (

<>

<h1>Component 4</h1>

<Component5 user={user} />

</>

);

}
function Component5({ user }) {

return (

<>

<h1>Component 5</h1>

<h2>{`Hello ${user} again!`}</h2>

</>

);

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

root.render(<Component1 />);

Run Example »

Even though components 2-4 did not need the state, they had to pass the
state along so that it could reach component 5.

w3schoolsCERTIFIED.2022

Get Certified!

Complete the React modules, do the exercises, take the exam and
become w3schools certified!!

$95 ENROLL

The Solution

The solution is to create context.

Create Context

To create context, you must Import createContext and initialize it:

import { useState, createContext } from "react";


import ReactDOM from "react-dom/client";

const UserContext = createContext()

Next we'll use the Context Provider to wrap the tree of components that
need the state Context.

Context Provider

Wrap child components in the Context Provider and supply the state
value.

function Component1() {

const [user, setUser] = useState("Jesse Hall");

return (

<UserContext.Provider value={user}>

<h1>{`Hello ${user}!`}</h1>

<Component2 user={user} />

</UserContext.Provider>

);

Now, all components in this tree will have access to the user Context.

Use the useContext Hook

In order to use the Context in a child component, we need to access it


using the useContext Hook.

First, include the useContext in the import statement:

import { useState, createContext, useContext } from "react";

Then you can access the user Context in all components:

function Component5() {

const user = useContext(UserContext);


return (

<>

<h1>Component 5</h1>

<h2>{`Hello ${user} again!`}</h2>

</>

);

Full Example
Example:

Here is the full example using React Context:

import { useState, createContext, useContext } from "react";

import ReactDOM from "react-dom/client";

const UserContext = createContext();

function Component1() {

const [user, setUser] = useState("Jesse Hall");

return (

<UserContext.Provider value={user}>

<h1>{`Hello ${user}!`}</h1>

<Component2 user={user} />

</UserContext.Provider>

);

}
function Component2() {

return (

<>

<h1>Component 2</h1>

<Component3 />

</>

);

function Component3() {

return (

<>

<h1>Component 3</h1>

<Component4 />

</>

);

function Component4() {

return (

<>

<h1>Component 4</h1>

<Component5 />

</>

);

}
function Component5() {

const user = useContext(UserContext);

return (

<>

<h1>Component 5</h1>

<h2>{`Hello ${user} again!`}</h2>

</>

);

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

root.render(<Component1 />);

Run Example »

React useRef Hook

❮ PreviousNext ❯

The useRef Hook allows you to persist values between renders.

It can be used to store a mutable value that does not cause a re-render
when updated.

It can be used to access a DOM element directly.

Does Not Cause Re-renders


If we tried to count how many times our application renders using
the useState Hook, we would be caught in an infinite loop since this
Hook itself causes a re-render.

To avoid this, we can use the useRef Hook.

Example:

Use useRef to track application renders.

import { useState, useEffect, useRef } from "react";

import ReactDOM from "react-dom/client";

function App() {

const [inputValue, setInputValue] = useState("");

const count = useRef(0);

useEffect(() => {

count.current = count.current + 1;

});

return (

<>

<input

type="text"

value={inputValue}

onChange={(e) => setInputValue(e.target.value)}

/>

<h1>Render Count: {count.current}</h1>

</>

);

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

root.render(<App />);

Run Example »

useRef() only returns one item. It returns an Object called current.

When we initialize useRef we set the initial value: useRef(0).

It's like doing this: const count = {current: 0}. We can access the count
by using count.current.

Run this on your computer and try typing in the input to see the
application render count increase.

w3schoolsCERTIFIED.2022

Get Certified!

Complete the React modules, do the exercises, take the exam and
become w3schools certified!!

$95 ENROLL

Accessing DOM Elements

In general, we want to let React handle all DOM manipulation.

But there are some instances where useRef can be used without causing


issues.

In React, we can add a ref attribute to an element to access it directly in


the DOM.

Example:

Use useRef to focus the input:

import { useRef } from "react";

import ReactDOM from "react-dom/client";


function App() {

const inputElement = useRef();

const focusInput = () => {

inputElement.current.focus();

};

return (

<>

<input type="text" ref={inputElement} />

<button onClick={focusInput}>Focus Input</button>

</>

);

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

root.render(<App />);

Run Example »

Tracking State Changes

The useRef Hook can also be used to keep track of previous state values.

This is because we are able to persist useRef values between renders.

Example:

Use useRef to keep track of previous state values:

import { useState, useEffect, useRef } from "react";

import ReactDOM from "react-dom/client";


function App() {

const [inputValue, setInputValue] = useState("");

const previousInputValue = useRef("");

useEffect(() => {

previousInputValue.current = inputValue;

}, [inputValue]);

return (

<>

<input

type="text"

value={inputValue}

onChange={(e) => setInputValue(e.target.value)}

/>

<h2>Current Value: {inputValue}</h2>

<h2>Previous Value: {previousInputValue.current}</h2>

</>

);

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

root.render(<App />);

Run Example »

This time we use a combination of useState, useEffect, and useRef to


keep track of the previous state.

In the useEffect, we are updating the useRef current value each time


the inputValue is updated by entering text into the input field.
React useReducer Hook

The useReducer Hook is similar to the useState Hook.

It allows for custom state logic.

If you find yourself keeping track of multiple pieces of state that rely on
complex logic, useReducer may be useful.

Syntax

The useReducer Hook accepts two arguments.

useReducer(<reducer>, <initialState>)

The reducer function contains your custom state logic and the initialState


can be a simple value but generally will contain an object.

The useReducer Hook returns the current state and a dispatch method.

Here is an example of useReducer in a counter app:

Example:

import { useReducer } from "react";

import ReactDOM from "react-dom/client";

const initialTodos = [

id: 1,

title: "Todo 1",

complete: false,

},

id: 2,

title: "Todo 2",

complete: false,

},

];
const reducer = (state, action) => {

switch (action.type) {

case "COMPLETE":

return state.map((todo) => {

if (todo.id === action.id) {

return { ...todo, complete: !todo.complete };

} else {

return todo;

});

default:

return state;

};

function Todos() {

const [todos, dispatch] = useReducer(reducer, initialTodos);

const handleComplete = (todo) => {

dispatch({ type: "COMPLETE", id: todo.id });

};

return (

<>

{todos.map((todo) => (

<div key={todo.id}>
<label>

<input

type="checkbox"

checked={todo.complete}

onChange={() => handleComplete(todo)}

/>

{todo.title}

</label>

</div>

))}

</>

);

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

root.render(<Todos />);

Run Example »

This is just the logic to keep track of the todo complete status.

All of the logic to add, delete, and complete a todo could be contained
within a single useReducer Hook by adding more actions.

React useRef Hook

❮ PreviousNext ❯

The useRef Hook allows you to persist values between renders.

It can be used to store a mutable value that does not cause a re-render
when updated.

It can be used to access a DOM element directly.


Does Not Cause Re-renders

If we tried to count how many times our application renders using


the useState Hook, we would be caught in an infinite loop since this
Hook itself causes a re-render.

To avoid this, we can use the useRef Hook.

Example:

Use useRef to track application renders.

import { useState, useEffect, useRef } from "react";

import ReactDOM from "react-dom/client";

function App() {

const [inputValue, setInputValue] = useState("");

const count = useRef(0);

useEffect(() => {

count.current = count.current + 1;

});

return (

<>

<input

type="text"

value={inputValue}

onChange={(e) => setInputValue(e.target.value)}


/>

<h1>Render Count: {count.current}</h1>

</>

);

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

root.render(<App />);

useRef() only returns one item. It returns an Object called current.

When we initialize useRef we set the initial value: useRef(0).

It's like doing this: const count = {current: 0}. We can access the count
by using count.current.

Run this on your computer and try typing in the input to see the
application render count increase.

w3schoolsCERTIFIED.2022

Get Certified!

Complete the React modules, do the exercises, take the exam and
become w3schools certified!!

$95 ENROLL

Accessing DOM Elements

In general, we want to let React handle all DOM manipulation.

But there are some instances where useRef can be used without causing


issues.

In React, we can add a ref attribute to an element to access it directly in


the DOM.

Example:
Use useRef to focus the input:

import { useRef } from "react";

import ReactDOM from "react-dom/client";

function App() {

const inputElement = useRef();

const focusInput = () => {

inputElement.current.focus();

};

return (

<>

<input type="text" ref={inputElement} />

<button onClick={focusInput}>Focus Input</button>

</>

);

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

root.render(<App />);

Run Example »

Tracking State Changes

The useRef Hook can also be used to keep track of previous state values.

This is because we are able to persist useRef values between renders.

Example:
Use useRef to keep track of previous state values:

import { useState, useEffect, useRef } from "react";

import ReactDOM from "react-dom/client";

function App() {

const [inputValue, setInputValue] = useState("");

const previousInputValue = useRef("");

useEffect(() => {

previousInputValue.current = inputValue;

}, [inputValue]);

return (

<>

<input

type="text"

value={inputValue}

onChange={(e) => setInputValue(e.target.value)}

/>

<h2>Current Value: {inputValue}</h2>

<h2>Previous Value: {previousInputValue.current}</h2>

</>

);

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

root.render(<App />);
Run Example »

This time we use a combination of useState, useEffect, and useRef to


keep track of the previous state.

In the useEffect, we are updating the useRef current value each time


the inputValue is updated by entering text into the input field.

❮ PreviousNext ❯

React useCallback Hook

❮ PreviousNext ❯

The React useCallback Hook returns a memoized callback function.

Think of memoization as caching a value so that it does not need to be


recalculated.

This allows us to isolate resource intensive functions so that they will


not automatically run on every render.

The useCallback Hook only runs when one of its dependencies update.

This can improve performance.

The useCallback and useMemo Hooks are similar. The main difference


is that useMemo returns a memoized value and useCallback returns a
memoized function. You can learn more about useMemo in the
useMemo chapter.

Problem

One reason to use useCallback is to prevent a component from re-


rendering unless its props have changed.

In this example, you might think that the Todos component will not re-
render unless the todos change:
This is a similar example to the one in the React.memo section.
Example:

index.js

import { useState } from "react";

import ReactDOM from "react-dom/client";

import Todos from "./Todos";

const App = () => {

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

const [todos, setTodos] = useState([]);

const increment = () => {

setCount((c) => c + 1);

};

const addTodo = () => {

setTodos((t) => [...t, "New Todo"]);

};

return (

<>

<Todos todos={todos} addTodo={addTodo} />

<hr />

<div>

Count: {count}

<button onClick={increment}>+</button>

</div>

</>
);

};

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

root.render(<App />);

Todos.js

import { memo } from "react";

const Todos = ({ todos, addTodo }) => {

console.log("child render");

return (

<>

<h2>My Todos</h2>

{todos.map((todo, index) => {

return <p key={index}>{todo}</p>;

})}

<button onClick={addTodo}>Add Todo</button>

</>

);

};

export default memo(Todos);

Run Example »

Try running this and click the count increment button.

You will notice that the Todos component re-renders even when


the todos do not change.
Why does this not work? We are using memo, so the Todos component
should not re-render since neither the todos state nor
the addTodo function are changing when the count is incremented.

This is because of something called "referential equality".

Every time a component re-renders, its functions get recreated. Because


of this, the addTodo function has actually changed.

w3schoolsCERTIFIED.2022

Get Certified!

Complete the React modules, do the exercises, take the exam and
become w3schools certified!!

$95 ENROLL

Solution

To fix this, we can use the useCallback hook to prevent the function


from being recreated unless necessary.

Use the useCallback Hook to prevent the Todos component from re-


rendering needlessly:

Example:

index.js

import { useState, useCallback } from "react";

import ReactDOM from "react-dom/client";

import Todos from "./Todos";

const App = () => {

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

const [todos, setTodos] = useState([]);

const increment = () => {


setCount((c) => c + 1);

};

const addTodo = useCallback(() => {

setTodos((t) => [...t, "New Todo"]);

}, [todos]);

return (

<>

<Todos todos={todos} addTodo={addTodo} />

<hr />

<div>

Count: {count}

<button onClick={increment}>+</button>

</div>

</>

);

};

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

root.render(<App />);

Todos.js

import { memo } from "react";

const Todos = ({ todos, addTodo }) => {

console.log("child render");

return (

<>
<h2>My Todos</h2>

{todos.map((todo, index) => {

return <p key={index}>{todo}</p>;

})}

<button onClick={addTodo}>Add Todo</button>

</>

);

};

export default memo(Todos);

Run Example »

Now the Todos component will only re-render when the todos prop


changes.

React useMemo Hook

❮ PreviousNext ❯

The React useMemo Hook returns a memoized value.

Think of memoization as caching a value so that it does not need to be


recalculated.

The useMemo Hook only runs when one of its dependencies update.

This can improve performance.

The useMemo and useCallback Hooks are similar. The main difference


is that useMemo returns a memoized value and useCallback returns a
memoized function. You can learn more about useCallback in
the useCallback chapter.

Performance
The useMemo Hook can be used to keep expensive, resource intensive
functions from needlessly running.

In this example, we have an expensive function that runs on every


render.

When changing the count or adding a todo, you will notice a delay in
execution.

Example:

A poor performing function. The expensiveCalculation function runs on


every render:

import { useState } from "react";

import ReactDOM from "react-dom/client";

const App = () => {

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

const [todos, setTodos] = useState([]);

const calculation = expensiveCalculation(count);

const increment = () => {

setCount((c) => c + 1);

};

const addTodo = () => {

setTodos((t) => [...t, "New Todo"]);

};

return (

<div>

<div>

<h2>My Todos</h2>

{todos.map((todo, index) => {


return <p key={index}>{todo}</p>;

})}

<button onClick={addTodo}>Add Todo</button>

</div>

<hr />

<div>

Count: {count}

<button onClick={increment}>+</button>

<h2>Expensive Calculation</h2>

{calculation}

</div>

</div>

);

};

const expensiveCalculation = (num) => {

console.log("Calculating...");

for (let i = 0; i < 1000000000; i++) {

num += 1;

return num;

};

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

root.render(<App />);

Run Example »
w3schoolsCERTIFIED.2022

Get Certified!

Complete the React modules, do the exercises, take the exam and
become w3schools certified!!

$95 ENROLL

Use useMemo

To fix this performance issue, we can use the useMemo Hook to


memoize the expensiveCalculation function. This will cause the function
to only run when needed.

We can wrap the expensive function call with useMemo.

The useMemoHook accepts a second parameter to declare dependencies.


The expensive function will only run when its dependencies have
changed.

In the following example, the expensive function will only run


when count is changed and not when todo's are added.

Example:

Performance example using the useMemo Hook:

import { useState, useMemo } from "react";

import ReactDOM from "react-dom/client";

const App = () => {

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

const [todos, setTodos] = useState([]);

const calculation = useMemo(() => expensiveCalculation(count),


[count]);

const increment = () => {

setCount((c) => c + 1);


};

const addTodo = () => {

setTodos((t) => [...t, "New Todo"]);

};

return (

<div>

<div>

<h2>My Todos</h2>

{todos.map((todo, index) => {

return <p key={index}>{todo}</p>;

})}

<button onClick={addTodo}>Add Todo</button>

</div>

<hr />

<div>

Count: {count}

<button onClick={increment}>+</button>

<h2>Expensive Calculation</h2>

{calculation}

</div>

</div>

);

};

const expensiveCalculation = (num) => {

console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {

num += 1;

return num;

};

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

root.render(<App />);

Run Example »
React Custom Hooks

❮ PreviousNext ❯

Hooks are reusable functions.

When you have component logic that needs to be used by multiple


components, we can extract that logic to a custom Hook.

Custom Hooks start with "use". Example: useFetch.

Build a Hook

In the following code, we are fetching data in our Home component and


displaying it.

We will use the JSONPlaceholder service to fetch fake data. This service


is great for testing applications when there is no existing data.

To learn more, check out the JavaScript Fetch API section.

Use the JSONPlaceholder service to fetch fake "todo" items and display
the titles on the page:

Example:

index.js:

import { useState, useEffect } from "react";


import ReactDOM from "react-dom/client";

const Home = () => {

const [data, setData] = useState(null);

useEffect(() => {

fetch("https://jsonplaceholder.typicode.com/todos")

.then((res) => res.json())

.then((data) => setData(data));

}, []);

return (

<>

{data &&

data.map((item) => {

return <p key={item.id}>{item.title}</p>;

})}

</>

);

};

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

root.render(<Home />);

Run Example »

The fetch logic may be needed in other components as well, so we will


extract that into a custom Hook.

Move the fetch logic to a new file to be used as a custom Hook:


Example:

useFetch.js:

import { useState, useEffect } from "react";

const useFetch = (url) => {

const [data, setData] = useState(null);

useEffect(() => {

fetch(url)

.then((res) => res.json())

.then((data) => setData(data));

}, [url]);

return [data];

};

export default useFetch;


index.js:

import ReactDOM from "react-dom/client";

import useFetch from "./useFetch";

const Home = () => {

const [data] = useFetch("https://jsonplaceholder.typicode.com/todos");

return (

<>

{data &&
data.map((item) => {

return <p key={item.id}>{item.title}</p>;

})}

</>

);

};

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

root.render(<Home />);

Run Example »

Example Explained

We have created a new file called useFetch.js containing a function


called useFetch which contains all of the logic needed to fetch our data.

We removed the hard-coded URL and replaced it with a url variable that


can be passed to the custom Hook.

Lastly, we are returning our data from our Hook.

In index.js, we are importing our useFetch Hook and utilizing it like any


other Hook. This is where we pass in the URL to fetch data from.

Now we can reuse this custom Hook in any component to fetch data
from any URL.

Introduction to Hooks

A Component in React can be created as a Class Component or


a function Component. When we want features like Managing State in
React Components or responding to Lifecycle methods then we will opt
for using Class Components.

Developers have encountered a wide variety of seemingly unconnected


problems in React over five years of writing and maintaining tens of
thousands of components.

And Majority of them are coming because of using Class Components. 

Now the question is What are the Problems of existing Class


Components

1. Wrapper Hell

2. Huge Components

3. Confusing Classes

4. classes don’t minify very well

We will discuss few of them in detail in this article and others in our
upcoming articles. 

React want to present an API out of the box that makes React easier to
build great UIs with the best Performance. 

Hooks are a new addition in React 16.8. They let you use state and other
React features without writing a class.

Hooks are functions that let you “hook into” React state and lifecycle
features from function components. Hooks don’t work inside classes —
they let you use React without classes.

To make function components more powerful, React has introduced


several built in hooks. 

Hooks in React are Classified into Basic Hooks, Additional Hooks.

Basic Hooks

• useState
• useEffect

• useContext

Additional Hooks

• useReducer

• useCallback

• useMemo

• useRef

• useImperativeHandle

• useLayoutEffect

• useDebugValue

We can also create Custom Hooks. 

Lets say we want to develop one Employee Component and we will


create it as a Class Component. 

We have created the below Component in our last article. 

class Employee extends React.Component{

constructor(props){

super(props);

this.state={

Name:''
}

changeName=(e)=>{

this.setState({Name:e.target.value});

render(){

return(

<div>

<h2>Welcome to Employee Component...</h2>

<p>

<label>Employee Name :

<input type="text" value={this.state.Name}


onChange={this.changeName}></input>

</label>
</p>

<p>

Entered Name is : <b>{this.state.Name}</b>

</p>

</div>

Lets Call this Employee Component and we will render that to our root
container. 

Save the changes, navigate to the browser. We can see the Output.

If we look at the code we have written, for a simple use case, we are
writing more lines of code. That includes writing constructor, calling
baseclass constructor. All that involves additional overhead to the
application performance. As the application complexity grows, even our
code becomes more and it becomes unmanageable. 

But as a developer, we don’t want our code to become unmanageable. 

Now we will develop a NewEmployee Component but this time we will


create it as a function component. 

If we look at our Employee Class Component, we have added one


property to our state object called as Name and this is initialized to
empty. Then we have created one function called as changeName using
which we are updating the state object. 

In the Same way, even we want to have one Name property and one
function to update the Name in our function Component as well. 

We wanted our Name to be Stateful. We want to store this Name in the


State object and we want to update the Name.

This is where we will make use of useState hook in react. 

Remember that hook is a function. So now we are going to call a


function called as useState. 

This useState function can take one argument that is initialiState value.
Unlike with classes, the state doesn’t have to be an object. We can keep
a number or a string if that’s all we need. In our case, we wanted the
state for Name, so we empty. 

useState function returns a pair of values: the current state and a function
that updates it. 

So we can write 

const [name,setName]=useState();

Here Name is the Property Name and setName is the function using
which we update the value of Name into our state Object. 

Lets write one function which will be called when there is a change in
the Name. 

With in this function, we will update the Name value to our state object
usin setName function. 

function changeName(e){

setName(e.target.value);

}
Copy
Lets return the div container, add one h2 Tag with text as Welcome to
New Employee Component…

Lets Place one input element and value of that input element should be
the name from our state object and we will call changeName function
when there is a change. 

Next lets display the Entered Name. 

return(

<div>

<h2>Welcome to New Employee Component...</h2>

<p>

<label>Employee Name :

<input type="text" value={name}

onChange={changeName}></input>

</label>

</p>

<p>

Entered Name is : <b>{name}</b>


</p>

</div>

Copy
Now instead of Calling the Employee Component, we will call our
NewEmployee Component. Save the changes, navigate to the browser. 

We can see that as we keep entering the Name, the entered Name is
displayed down to our input element. 

We are able to achieve same functionality through a functional


component. 

If we observe our NewEmployee Component Code, we don’t have a


constructor, we are not calling the base class constructor. We have not
implemented any render method. 

We are Calling a function and it is returning us the output. 

Now lets say we want to initialize our name value to Pragim. So we can
go to our useState function and pass the value as the input to the
function. 

const [name,setName]=useState('Pragim);

We can save the changes. Navigate to the browser. 

We can see that our textbox is holding the value by default and we can
change if needed. 

we have introduced ourselves to the concept of Hooks in React. We have


a lot to learn and We will continue discussing more about Hooks in our
Upcoming articles. 

we have just seen an intro to Hooks in React. We will discuss more


about Hooks in our Upcoming articles. 
useState Hook

In this article, we will discuss about useState deeper in React.

We have created NewEmployee Component in our last article. 

Our Employee Component is having one input element. Now lets say we
want to have another input using which we can enter Employee
Location. 

We can repeat the same steps for Location as well.

Lets copy the paragraph tag and paste. 

We can declare Multiple State Variables. 

const [location,setLocation]=useState();

Copy

Lets display the entered location as well in the Paragraph tag.

<p>

<label>Employee Location :

<input type="text" name="Location" value={location}

onChange={changeEmployeeLocation}></input>

</label>

</p>

Copy

Save the changes, navigate to the browser. We can see the output.

Now if we want to build an employee creation form where we will also


have inputs for Employee Id and employee salary as well, the current
way of creating the multiple state variables may not be the right
approach.

State variables can hold objects and arrays just fine, so you can still
group related data together.
Lets create an object and pass it to the useState function. The object will
hold employee Id, name, location and Salary. 

Lets create a function named as changeEmployee and with in this


function we will call setEmployee function and we will update the state
object.

We will use spread operator to pass the current employee object data and
we will update the respective elements value. 

Now we will update our input elements to use this objects data. Don’t
forget to assign the name to each input element name. Save these
changes. Navigate to the browser. We can see the output as we type in
the data.

Lets save the changes, navigate to the browser. We can see the output. 

import ReactDOM from "react-dom";

import React, { Component, useState } from "react";

function NewEmployee(){

const
[employee,setEmployeeData]=useState({Id:'',Name:'',Location:'',Salary:''
});

function changeEmployeeInfo(e){

setEmployeeData({...employee,[e.target.name]:e.target.value});

return(

<div>

<h2>Welcome to Employee Component...</h2>

<p>

<label>Employee ID :

<input type="text" name="Id" value={employee.Id}


onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

<label>Employee Name :

<input type="text" name="Name" value={employee.Name}

onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

<label>Employee Location :

<input type="text" name="Location"


value={employee.Location}

onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

<label>Employee Salary :

<input type="text" name="Salary" value={employee.Salary}

onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

Employee ID is : <b>{employee.Id}</b>, Name is :


<b>{employee.Name}</b> ,

Location is : <b>{employee.Location}</b> and Salary is :


<b>{employee.Salary}</b>

</p>
<SalaryComponent salary={employee.Salary}
onSalaryChange={changeEmployeeInfo}></SalaryComponent>

</div>

const element=<NewEmployee></NewEmployee>

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

Copy

We have seen how do we use state in a function component. 

useEffect

Many times, we want to run some additional code after React has
updated the DOM.

That code can be getting the Data by Calling a Web API or Setting up
subscriptions or writing the logs after the DOM is ready. 

If we want to write such additional code in Class Components, we have


lifecycle methods like componentDidMount, componentDidUpdate
methods. 

What if, if want to write such code in the case of function components.

Lets Open index.js file from our demo-project. 

Lets create EmployeeReports Component using which we display the


list of Employees by fetching it from API.

We know how to send a Web API request and get the data from our
React Application. But now question is where should we write the code. 

Remember that we want to execute that code after DOM is ready. 


If we think of writing just before our return statement, just lets do one
thing. We will write a console log here which shows us the DOM status. 

console.log(document.readyState);

Copy
Call our Employee Reports Component and render that to our root
container. 

At this point of time, our table will be empty without data because we
are yet to send the Web API request to get the data. 

Save the changes, navigate to the browser. 

We can see the table but no data. Lets open developer tools, we can see
the status. It says that loading. 

That means we should not be writing the Code here. 

So where should we write the code which should get executed after our
DOM is ready. 

This is where we will make use of another hook in React called


as useEffect. 

useEffect is a function that runs when the component is first rendered,


and on every subsequent re-render/update.

We can think of useEffect Hook


as componentDidMount, componentDidUpdate,
and componentWillUnmount combined.

Lets call useEffect function and it takes one callback function as a


parameter. 

We will write one arrow function. Inside that function, lets place the
same console.log statement we have written earlier. Save the changes,
navigate to the browser. 

Open developer tools and we can see that the status is Complete. 

Our DOM is ready and we can do all the other operations we want now. 
Lets go back to Visual studio code, now within this useEffect, lets place
the code using which we will send the API request. We have discussed
this already in our previous sessions. I am pasting that code here. When
we get the response from our Web API, we will call our setEmployees
function and we will pass the list to that. 

Save the changes, navigate to the browser. We can see that employee
details are being displayed here. 

When the DOM is ready, we are sending the API request, getting the
employees data and updating our employees state variable by calling
setEmployees method. But this has a Problem. Remember that when
there is any change in the properties data or state data of a component,
then that component gets re-rendered. 

Resulting our useEffect function gets called again. It will send an API
request, get the data and assign it to employees state variable. That will
make the component gets re-rendered and it will go into infinite loop. 

Lets add an alert. Save the changes, navigate to the browser. We can see
that we get the alert again and again. 

If you want to run an effect only once (on mount and unmount), you can
pass an empty array ([]) as a second argument. This tells React that your
effect doesn’t depend on any values from props or state, so it never
needs to re-run.

import ReactDOM from "react-dom";

import React, { Component, useState, useEffect } from "react";

function EmployeeComponent(){

const [employees,setEmployees]=useState([]);

useEffect(()=>{

alert('We are in useEffect function');

fetch("https://localhost:44306/api/Employee")

.then(res => res.json())


.then(

(result) => {

setEmployees(result);

);

},[]);

return(

<div>

<h2>Employees Data...</h2>

<table>

<thead>

<tr>

<th>Id</th>

<th>Name</th>

<th>Location</th>

<th>Salary</th>

</tr>

</thead>

<tbody>

{employees.map(emp=>(

<tr key={emp.Id}>

<td>{emp.Id}</td>

<td>{emp.Name}</td>

<td>{emp.Location}</td>

<td>{emp.Salary}</td>

</tr>
))}

</tbody>

</table>

</div>

const element=<EmployeeComponent></EmployeeComponent>

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

useContext Hook

In a typical React application, data is passed top-down (parent to child)


via props, but this can be difficult for certain types of props (e.g. locale
preference, UI theme) that are required by many components which are
Nested at different levels within an application. 

In this article, we will understand how we use Context to pass the data
between components at different nesting levels.

Lets take a look at one example. When an Employee is Logged into the
React application, we have a Nesting of Components which are making
our UI. 

They are App Component, Employee Component and Salary


Component. App Component has an Employee Object and this data is
needed by Employee Component and Salary Component in Order to
function.
Context provides a way to pass data through the component tree without
having to pass props down manually at every level.

Context provides a way to share values between components without


having to explicitly pass a prop through every level of the tree.

Context is primarily used when some data needs to be accessible by


many components at different nesting levels.

We have discussed this in the case of Class Components. We will


understand how do we use the context in the case of Function
Components. 

We will create three functional components. Named App Component,


Employee Component and Salary Component. 

Lets Call the Salary Component from Employee Component and Call
the Employee Component from App Component.

Call the App Component and render it to our DOM.


In App Component, lets create one employee state variable and a
function to update the employee data using useState hook and we will
initialize the state.

This employee object is needed by employee Component and by Salary


Component. 

Lets see how do we do that using Context in React. 

Lets create context object using React.createContext Method.

const EmployeeContext = React.createContext();

Copy

using the EmployeeContext object, we will pass the data from


AppComponent to the Employee Component and then from the
Employee Component to the Salary Component. 

Lets go to App Component, we modify the way how Employee


Component is being Called from App Component. 

So that Employee Component can receive the data from App Component
and pass that to the Child Components of Employee Component
implicitly. 

Every Context object comes with a Provider React component that


allows consuming components to subscribe to context changes.

Context Provider Accepts a value property to be passed to consuming


components that are descendants of this Provider.

<EmpContext.Provider value={empData}>

<Employee/>

</EmpContext.Provider>

Copy
Now this empData can be accessed in both Employee Component and
Salary Component using useContext hook in React. 

Lets go to Employee Component, get the Employee Context using


useContext hook. 

We can display the Employee details by reading from the context. 

We can do the Same in Salary Component as well. 

Save the Changes, navigate to the browser. We can see the Output. 

We can see that our employee data from App Component is accessed by
the 

Components which are placed at different Nesting Levels. 

One Level is from App Component to Employee Component and the


Second one is from Employee to Salary Component. 

import ReactDOM from "react-dom";

import React, { Component, useState, useContext } from "react";

const employeeContext=React.createContext();

function App(){

const [employee,setEmployee]=useState({Id:101,Name:'Pragim',

Location:'Bangalore',Salary:12345});

return(

<div>

<h2>Welcome to App Component...</h2>

<employeeContext.Provider value={employee}>

<Employee></Employee>
</employeeContext.Provider>

</div>

);

function Employee(){

let context=useContext(employeeContext);

return(

<div>

<h2>Welcome to Employee Component...</h2>

<p>

<label>Employee ID : <b>{context.Id}</b></label>

</p>

<p>

<label>Employee Name : <b>{context.Name}</b></label>

</p>

<Salary></Salary>

</div>

);

function Salary(){

let context=useContext(employeeContext);

return(

<div>
<h2>Welcome to Salary Component...</h2>

<p>

<label>Employee ID : <b>{context.Id}</b></label>

</p>

<p>

<label>Employee Salary : <b>{context.Salary}</b></label>

</p>

</div>

);

const element=<App></App>

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

Introduction to Hooks

We know that a Component in React can be created as a Class


Component or a function Component. We have discussed that when
we want features like Managing State in React Components or
responding to Lifecycle methods then we will opt for using Class
Components.

Developers have encountered a wide variety of seemingly unconnected


problems in React over five years of writing and maintaining tens of
thousands of components.

And Majority of them are coming because of using Class Components. 

Now the question is What are the Problems of existing Class


Components

1. Wrapper Hell
2. Huge Components

3. Confusing Classes

4. classes don’t minify very well

We will discuss few of them in detail in this article and others in our
upcoming articles. 

React want to present an API out of the box that makes React easier to
build great UIs with the best Performance. 

Hooks are a new addition in React 16.8. They let you use state and other
React features without writing a class.

Hooks are functions that let you “hook into” React state and lifecycle
features from function components. Hooks don’t work inside classes —
they let you use React without classes.

To make function components more powerful, React has introduced


several built in hooks. 

Hooks in React are Classified into Basic Hooks, Additional Hooks.

Basic Hooks

• useState

• useEffect

• useContext

Additional Hooks

• useReducer

• useCallback

• useMemo

• useRef
• useImperativeHandle

• useLayoutEffect

• useDebugValue

We can also create Custom Hooks. 

We will discuss about useState Hook in this article and we will discuss
about others in our upcoming articles. In this Process, we will also
understand how Hooks make our React Code better. 

Lets say we want to develop one Employee Component and we will


create it as a Class Component. 

We have created the below Component in our last article. 

class Employee extends React.Component{

constructor(props){

super(props);

this.state={

Name:''

changeName=(e)=>{
this.setState({Name:e.target.value});

render(){

return(

<div>

<h2>Welcome to Employee Component...</h2>

<p>

<label>Employee Name :

<input type="text" value={this.state.Name}


onChange={this.changeName}></input>

</label>

</p>

<p>

Entered Name is : <b>{this.state.Name}</b>


</p>

</div>

Copy
Lets Call this Employee Component and we will render that to our root
container. 

Save the changes, navigate to the browser. We can see the Output.

If we look at the code we have written, for a simple use case, we are
writing more lines of code. That includes writing constructor, calling
baseclass constructor. All that involves additional overhead to the
application performance. As the application complexity grows, even our
code becomes more and it becomes unmanageable. 

But as a developer, we don’t want our code to become unmanageable. 

Now we will develop a NewEmployee Component but this time we will


create it as a function component. 

If we look at our Employee Class Component, we have added one


property to our state object called as Name and this is initialized to
empty. Then we have created one function called as changeName using
which we are updating the state object. 

In the Same way, even we want to have one Name property and one
function to update the Name in our function Component as well. 

We wanted our Name to be Stateful. We want to store this Name in the


State object and we want to update the Name.
This is where we will make use of useState hook in react. 

Remember that hook is a function. So now we are going to call a


function called as useState. 

This useState function can take one argument that is initialiState value.
Unlike with classes, the state doesn’t have to be an object. We can keep
a number or a string if that’s all we need. In our case, we wanted the
state for Name, so we empty. 

useState function returns a pair of values: the current state and a function
that updates it. 

So we can write 

const [name,setName]=useState();

Here Name is the Property Name and setName is the function using
which we update the value of Name into our state Object. 

Lets write one function which will be called when there is a change in
the Name. 

With in this function, we will update the Name value to our state object
usin setName function. 

function changeName(e){

setName(e.target.value);

Copy
Lets return the div container, add one h2 Tag with text as Welcome to
New Employee Component…

Lets Place one input element and value of that input element should be
the name from our state object and we will call changeName function
when there is a change. 
Next lets display the Entered Name. 

return(

<div>

<h2>Welcome to New Employee Component...</h2>

<p>

<label>Employee Name :

<input type="text" value={name}

onChange={changeName}></input>

</label>

</p>

<p>

Entered Name is : <b>{name}</b>

</p>

</div>
)

Copy
Now instead of Calling the Employee Component, we will call our
NewEmployee Component. Save the changes, navigate to the browser. 

We can see that as we keep entering the Name, the entered Name is
displayed down to our input element. 

We are able to achieve same functionality through a functional


component. 

If we observe our NewEmployee Component Code, we don’t have a


constructor, we are not calling the base class constructor. We have not
implemented any render method. 

We are Calling a function and it is returning us the output. 

Now lets say we want to initialize our name value to Pragim. So we can
go to our useState function and pass the value as the input to the
function. 

const [name,setName]=useState('Pragim);

We can save the changes. Navigate to the browser. 

We can see that our textbox is holding the value by default and we can
change if needed. 

we have introduced ourselves to the concept of Hooks in React. We have


a lot to learn and We will continue discussing more about Hooks in our
Upcoming articles. 

we have just seen an intro to Hooks in React. We will discuss more


about Hooks in our Upcoming articles. 

useState Hook

In this article, we will discuss about useState deeper in React.

We have created NewEmployee Component in our last article. 


Our Employee Component is having one input element. Now lets say we
want to have another input using which we can enter Employee
Location. 

We can repeat the same steps for Location as well.

Lets copy the paragraph tag and paste. 

We can declare Multiple State Variables. 

const [location,setLocation]=useState();

Copy

Lets display the entered location as well in the Paragraph tag.

<p>

<label>Employee Location :

<input type="text" name="Location" value={location}

onChange={changeEmployeeLocation}></input>

</label>

</p>

Copy

Save the changes, navigate to the browser. We can see the output.

Now if we want to build an employee creation form where we will also


have inputs for Employee Id and employee salary as well, the current
way of creating the multiple state variables may not be the right
approach.

State variables can hold objects and arrays just fine, so you can still
group related data together.

Lets create an object and pass it to the useState function. The object will
hold employee Id, name, location and Salary. 

Lets create a function named as changeEmployee and with in this


function we will call setEmployee function and we will update the state
object.
We will use spread operator to pass the current employee object data and
we will update the respective elements value. 

Now we will update our input elements to use this objects data. Don’t
forget to assign the name to each input element name. Save these
changes. Navigate to the browser. We can see the output as we type in
the data.

Lets save the changes, navigate to the browser. We can see the output. 

import ReactDOM from "react-dom";

import React, { Component, useState } from "react";

function NewEmployee(){

const
[employee,setEmployeeData]=useState({Id:'',Name:'',Location:'',Salary:''
});

function changeEmployeeInfo(e){

setEmployeeData({...employee,[e.target.name]:e.target.value});

return(

<div>

<h2>Welcome to Employee Component...</h2>

<p>

<label>Employee ID :

<input type="text" name="Id" value={employee.Id}

onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

<label>Employee Name :
<input type="text" name="Name" value={employee.Name}

onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

<label>Employee Location :

<input type="text" name="Location"


value={employee.Location}

onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

<label>Employee Salary :

<input type="text" name="Salary" value={employee.Salary}

onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

Employee ID is : <b>{employee.Id}</b>, Name is :


<b>{employee.Name}</b> ,

Location is : <b>{employee.Location}</b> and Salary is :


<b>{employee.Salary}</b>

</p>

<SalaryComponent salary={employee.Salary}
onSalaryChange={changeEmployeeInfo}></SalaryComponent>

</div>

}
const element=<NewEmployee></NewEmployee>

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

Copy

We have seen how do we use state in a function component. 

useEffect

Many times, we want to run some additional code after React has
updated the DOM.

That code can be getting the Data by Calling a Web API or Setting up
subscriptions or writing the logs after the DOM is ready. 

If we want to write such additional code in Class Components, we have


lifecycle methods like componentDidMount, componentDidUpdate
methods. 

What if, if want to write such code in the case of function components.

Lets Open index.js file from our demo-project. 

Lets create EmployeeReports Component using which we display the


list of Employees by fetching it from API.

We know how to send a Web API request and get the data from our
React Application. But now question is where should we write the code. 

Remember that we want to execute that code after DOM is ready. 

If we think of writing just before our return statement, just lets do one
thing. We will write a console log here which shows us the DOM status. 

console.log(document.readyState);

Copy
Call our Employee Reports Component and render that to our root
container. 
At this point of time, our table will be empty without data because we
are yet to send the Web API request to get the data. 

Save the changes, navigate to the browser. 

We can see the table but no data. Lets open developer tools, we can see
the status. It says that loading. 

That means we should not be writing the Code here. 

So where should we write the code which should get executed after our
DOM is ready. 

This is where we will make use of another hook in React called


as useEffect. 

useEffect is a function that runs when the component is first rendered,


and on every subsequent re-render/update.

We can think of useEffect Hook


as componentDidMount, componentDidUpdate,
and componentWillUnmount combined.

Lets call useEffect function and it takes one callback function as a


parameter. 

We will write one arrow function. Inside that function, lets place the
same console.log statement we have written earlier. Save the changes,
navigate to the browser. 

Open developer tools and we can see that the status is Complete. 

Our DOM is ready and we can do all the other operations we want now. 

Lets go back to Visual studio code, now within this useEffect, lets place
the code using which we will send the API request. We have discussed
this already in our previous sessions. I am pasting that code here. When
we get the response from our Web API, we will call our setEmployees
function and we will pass the list to that. 

Save the changes, navigate to the browser. We can see that employee
details are being displayed here. 
When the DOM is ready, we are sending the API request, getting the
employees data and updating our employees state variable by calling
setEmployees method. But this has a Problem. Remember that when
there is any change in the properties data or state data of a component,
then that component gets re-rendered. 

Resulting our useEffect function gets called again. It will send an API
request, get the data and assign it to employees state variable. That will
make the component gets re-rendered and it will go into infinite loop. 

Lets add an alert. Save the changes, navigate to the browser. We can see
that we get the alert again and again. 

If you want to run an effect only once (on mount and unmount), you can
pass an empty array ([]) as a second argument. This tells React that your
effect doesn’t depend on any values from props or state, so it never
needs to re-run.

import ReactDOM from "react-dom";

import React, { Component, useState, useEffect } from "react";

function EmployeeComponent(){

const [employees,setEmployees]=useState([]);

useEffect(()=>{

alert('We are in useEffect function');

fetch("https://localhost:44306/api/Employee")

.then(res => res.json())

.then(

(result) => {

setEmployees(result);

);

},[]);
return(

<div>

<h2>Employees Data...</h2>

<table>

<thead>

<tr>

<th>Id</th>

<th>Name</th>

<th>Location</th>

<th>Salary</th>

</tr>

</thead>

<tbody>

{employees.map(emp=>(

<tr key={emp.Id}>

<td>{emp.Id}</td>

<td>{emp.Name}</td>

<td>{emp.Location}</td>

<td>{emp.Salary}</td>

</tr>

))}

</tbody>

</table>

</div>

}
const element=<EmployeeComponent></EmployeeComponent>

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

useContext Hook

In a typical React application, data is passed top-down (parent to child)


via props, but this can be difficult for certain types of props (e.g. locale
preference, UI theme) that are required by many components which are
Nested at different levels within an application. 

In this article, we will understand how we use Context to pass the data
between components at different nesting levels.

Lets take a look at one example. When an Employee is Logged into the
React application, we have a Nesting of Components which are making
our UI. 

They are App Component, Employee Component and Salary


Component. App Component has an Employee Object and this data is
needed by Employee Component and Salary Component in Order to
function.
Context provides a way to pass data through the component tree without
having to pass props down manually at every level.

Context provides a way to share values between components without


having to explicitly pass a prop through every level of the tree.

Context is primarily used when some data needs to be accessible by


many components at different nesting levels.

We have discussed this in the case of Class Components. We will


understand how do we use the context in the case of Function
Components. 

We will create three functional components. Named App Component,


Employee Component and Salary Component. 

Lets Call the Salary Component from Employee Component and Call
the Employee Component from App Component.

Call the App Component and render it to our DOM.


In App Component, lets create one employee state variable and a
function to update the employee data using useState hook and we will
initialize the state.

This employee object is needed by employee Component and by Salary


Component. 

Lets see how do we do that using Context in React. 

Lets create context object using React.createContext Method.

const EmployeeContext = React.createContext();

Copy

using the EmployeeContext object, we will pass the data from


AppComponent to the Employee Component and then from the
Employee Component to the Salary Component. 

Lets go to App Component, we modify the way how Employee


Component is being Called from App Component. 

So that Employee Component can receive the data from App Component
and pass that to the Child Components of Employee Component
implicitly. 

Every Context object comes with a Provider React component that


allows consuming components to subscribe to context changes.

Context Provider Accepts a value property to be passed to consuming


components that are descendants of this Provider.

<EmpContext.Provider value={empData}>

<Employee/>

</EmpContext.Provider>

Copy
Now this empData can be accessed in both Employee Component and
Salary Component using useContext hook in React. 

Lets go to Employee Component, get the Employee Context using


useContext hook. 

We can display the Employee details by reading from the context. 

We can do the Same in Salary Component as well. 

Save the Changes, navigate to the browser. We can see the Output. 

We can see that our employee data from App Component is accessed by
the 

Components which are placed at different Nesting Levels. 

One Level is from App Component to Employee Component and the


Second one is from Employee to Salary Component. 

import ReactDOM from "react-dom";

import React, { Component, useState, useContext } from "react";

const employeeContext=React.createContext();

function App(){

const [employee,setEmployee]=useState({Id:101,Name:'Pragim',

Location:'Bangalore',Salary:12345});

return(

<div>

<h2>Welcome to App Component...</h2>

<employeeContext.Provider value={employee}>

<Employee></Employee>
</employeeContext.Provider>

</div>

);

function Employee(){

let context=useContext(employeeContext);

return(

<div>

<h2>Welcome to Employee Component...</h2>

<p>

<label>Employee ID : <b>{context.Id}</b></label>

</p>

<p>

<label>Employee Name : <b>{context.Name}</b></label>

</p>

<Salary></Salary>

</div>

);

function Salary(){

let context=useContext(employeeContext);

return(

<div>
<h2>Welcome to Salary Component...</h2>

<p>

<label>Employee ID : <b>{context.Id}</b></label>

</p>

<p>

<label>Employee Salary : <b>{context.Salary}</b></label>

</p>

</div>

);

const element=<App></App>

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

Introduction to Hooks

We know that a Component in React can be created as a Class


Component or a function Component. We have discussed that when
we want features like Managing State in React Components or
responding to Lifecycle methods then we will opt for using Class
Components.

Developers have encountered a wide variety of seemingly unconnected


problems in React over five years of writing and maintaining tens of
thousands of components.

And Majority of them are coming because of using Class Components. 

Now the question is What are the Problems of existing Class


Components

1. Wrapper Hell
2. Huge Components

3. Confusing Classes

4. classes don’t minify very well

We will discuss few of them in detail in this article and others in our
upcoming articles. 

React want to present an API out of the box that makes React easier to
build great UIs with the best Performance. 

Hooks are a new addition in React 16.8. They let you use state and other
React features without writing a class.

Hooks are functions that let you “hook into” React state and lifecycle
features from function components. Hooks don’t work inside classes —
they let you use React without classes.

To make function components more powerful, React has introduced


several built in hooks. 

Hooks in React are Classified into Basic Hooks, Additional Hooks.

Basic Hooks

• useState

• useEffect

• useContext

Additional Hooks

• useReducer

• useCallback

• useMemo

• useRef
• useImperativeHandle

• useLayoutEffect

• useDebugValue

We can also create Custom Hooks. 

We will discuss about useState Hook in this article and we will discuss
about others in our upcoming articles. In this Process, we will also
understand how Hooks make our React Code better. 

Lets say we want to develop one Employee Component and we will


create it as a Class Component. 

We have created the below Component in our last article. 

class Employee extends React.Component{

constructor(props){

super(props);

this.state={

Name:''

changeName=(e)=>{
this.setState({Name:e.target.value});

render(){

return(

<div>

<h2>Welcome to Employee Component...</h2>

<p>

<label>Employee Name :

<input type="text" value={this.state.Name}


onChange={this.changeName}></input>

</label>

</p>

<p>

Entered Name is : <b>{this.state.Name}</b>


</p>

</div>

Copy
Lets Call this Employee Component and we will render that to our root
container. 

Save the changes, navigate to the browser. We can see the Output.

If we look at the code we have written, for a simple use case, we are
writing more lines of code. That includes writing constructor, calling
baseclass constructor. All that involves additional overhead to the
application performance. As the application complexity grows, even our
code becomes more and it becomes unmanageable. 

But as a developer, we don’t want our code to become unmanageable. 

Now we will develop a NewEmployee Component but this time we will


create it as a function component. 

If we look at our Employee Class Component, we have added one


property to our state object called as Name and this is initialized to
empty. Then we have created one function called as changeName using
which we are updating the state object. 

In the Same way, even we want to have one Name property and one
function to update the Name in our function Component as well. 

We wanted our Name to be Stateful. We want to store this Name in the


State object and we want to update the Name.
This is where we will make use of useState hook in react. 

Remember that hook is a function. So now we are going to call a


function called as useState. 

This useState function can take one argument that is initialiState value.
Unlike with classes, the state doesn’t have to be an object. We can keep
a number or a string if that’s all we need. In our case, we wanted the
state for Name, so we empty. 

useState function returns a pair of values: the current state and a function
that updates it. 

So we can write 

const [name,setName]=useState();

Here Name is the Property Name and setName is the function using
which we update the value of Name into our state Object. 

Lets write one function which will be called when there is a change in
the Name. 

With in this function, we will update the Name value to our state object
usin setName function. 

function changeName(e){

setName(e.target.value);

Copy
Lets return the div container, add one h2 Tag with text as Welcome to
New Employee Component…

Lets Place one input element and value of that input element should be
the name from our state object and we will call changeName function
when there is a change. 
Next lets display the Entered Name. 

return(

<div>

<h2>Welcome to New Employee Component...</h2>

<p>

<label>Employee Name :

<input type="text" value={name}

onChange={changeName}></input>

</label>

</p>

<p>

Entered Name is : <b>{name}</b>

</p>

</div>
)

Copy
Now instead of Calling the Employee Component, we will call our
NewEmployee Component. Save the changes, navigate to the browser. 

We can see that as we keep entering the Name, the entered Name is
displayed down to our input element. 

We are able to achieve same functionality through a functional


component. 

If we observe our NewEmployee Component Code, we don’t have a


constructor, we are not calling the base class constructor. We have not
implemented any render method. 

We are Calling a function and it is returning us the output. 

Now lets say we want to initialize our name value to Pragim. So we can
go to our useState function and pass the value as the input to the
function. 

const [name,setName]=useState('Pragim);

We can save the changes. Navigate to the browser. 

We can see that our textbox is holding the value by default and we can
change if needed. 

we have introduced ourselves to the concept of Hooks in React. We have


a lot to learn and We will continue discussing more about Hooks in our
Upcoming articles. 

we have just seen an intro to Hooks in React. We will discuss more


about Hooks in our Upcoming articles. 

useState Hook

In this article, we will discuss about useState deeper in React.

We have created NewEmployee Component in our last article. 


Our Employee Component is having one input element. Now lets say we
want to have another input using which we can enter Employee
Location. 

We can repeat the same steps for Location as well.

Lets copy the paragraph tag and paste. 

We can declare Multiple State Variables. 

const [location,setLocation]=useState();

Copy

Lets display the entered location as well in the Paragraph tag.

<p>

<label>Employee Location :

<input type="text" name="Location" value={location}

onChange={changeEmployeeLocation}></input>

</label>

</p>

Copy

Save the changes, navigate to the browser. We can see the output.

Now if we want to build an employee creation form where we will also


have inputs for Employee Id and employee salary as well, the current
way of creating the multiple state variables may not be the right
approach.

State variables can hold objects and arrays just fine, so you can still
group related data together.

Lets create an object and pass it to the useState function. The object will
hold employee Id, name, location and Salary. 

Lets create a function named as changeEmployee and with in this


function we will call setEmployee function and we will update the state
object.
We will use spread operator to pass the current employee object data and
we will update the respective elements value. 

Now we will update our input elements to use this objects data. Don’t
forget to assign the name to each input element name. Save these
changes. Navigate to the browser. We can see the output as we type in
the data.

Lets save the changes, navigate to the browser. We can see the output. 

import ReactDOM from "react-dom";

import React, { Component, useState } from "react";

function NewEmployee(){

const
[employee,setEmployeeData]=useState({Id:'',Name:'',Location:'',Salary:''
});

function changeEmployeeInfo(e){

setEmployeeData({...employee,[e.target.name]:e.target.value});

return(

<div>

<h2>Welcome to Employee Component...</h2>

<p>

<label>Employee ID :

<input type="text" name="Id" value={employee.Id}

onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

<label>Employee Name :
<input type="text" name="Name" value={employee.Name}

onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

<label>Employee Location :

<input type="text" name="Location"


value={employee.Location}

onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

<label>Employee Salary :

<input type="text" name="Salary" value={employee.Salary}

onChange={changeEmployeeInfo}></input>

</label>

</p>

<p>

Employee ID is : <b>{employee.Id}</b>, Name is :


<b>{employee.Name}</b> ,

Location is : <b>{employee.Location}</b> and Salary is :


<b>{employee.Salary}</b>

</p>

<SalaryComponent salary={employee.Salary}
onSalaryChange={changeEmployeeInfo}></SalaryComponent>

</div>

}
const element=<NewEmployee></NewEmployee>

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

Copy

We have seen how do we use state in a function component. 

useEffect

Many times, we want to run some additional code after React has
updated the DOM.

That code can be getting the Data by Calling a Web API or Setting up
subscriptions or writing the logs after the DOM is ready. 

If we want to write such additional code in Class Components, we have


lifecycle methods like componentDidMount, componentDidUpdate
methods. 

What if, if want to write such code in the case of function components.

Lets Open index.js file from our demo-project. 

Lets create EmployeeReports Component using which we display the


list of Employees by fetching it from API.

We know how to send a Web API request and get the data from our
React Application. But now question is where should we write the code. 

Remember that we want to execute that code after DOM is ready. 

If we think of writing just before our return statement, just lets do one
thing. We will write a console log here which shows us the DOM status. 

console.log(document.readyState);

Copy
Call our Employee Reports Component and render that to our root
container. 
At this point of time, our table will be empty without data because we
are yet to send the Web API request to get the data. 

Save the changes, navigate to the browser. 

We can see the table but no data. Lets open developer tools, we can see
the status. It says that loading. 

That means we should not be writing the Code here. 

So where should we write the code which should get executed after our
DOM is ready. 

This is where we will make use of another hook in React called


as useEffect. 

useEffect is a function that runs when the component is first rendered,


and on every subsequent re-render/update.

We can think of useEffect Hook


as componentDidMount, componentDidUpdate,
and componentWillUnmount combined.

Lets call useEffect function and it takes one callback function as a


parameter. 

We will write one arrow function. Inside that function, lets place the
same console.log statement we have written earlier. Save the changes,
navigate to the browser. 

Open developer tools and we can see that the status is Complete. 

Our DOM is ready and we can do all the other operations we want now. 

Lets go back to Visual studio code, now within this useEffect, lets place
the code using which we will send the API request. We have discussed
this already in our previous sessions. I am pasting that code here. When
we get the response from our Web API, we will call our setEmployees
function and we will pass the list to that. 

Save the changes, navigate to the browser. We can see that employee
details are being displayed here. 
When the DOM is ready, we are sending the API request, getting the
employees data and updating our employees state variable by calling
setEmployees method. But this has a Problem. Remember that when
there is any change in the properties data or state data of a component,
then that component gets re-rendered. 

Resulting our useEffect function gets called again. It will send an API
request, get the data and assign it to employees state variable. That will
make the component gets re-rendered and it will go into infinite loop. 

Lets add an alert. Save the changes, navigate to the browser. We can see
that we get the alert again and again. 

If you want to run an effect only once (on mount and unmount), you can
pass an empty array ([]) as a second argument. This tells React that your
effect doesn’t depend on any values from props or state, so it never
needs to re-run.

import ReactDOM from "react-dom";

import React, { Component, useState, useEffect } from "react";

function EmployeeComponent(){

const [employees,setEmployees]=useState([]);

useEffect(()=>{

alert('We are in useEffect function');

fetch("https://localhost:44306/api/Employee")

.then(res => res.json())

.then(

(result) => {

setEmployees(result);

);

},[]);
return(

<div>

<h2>Employees Data...</h2>

<table>

<thead>

<tr>

<th>Id</th>

<th>Name</th>

<th>Location</th>

<th>Salary</th>

</tr>

</thead>

<tbody>

{employees.map(emp=>(

<tr key={emp.Id}>

<td>{emp.Id}</td>

<td>{emp.Name}</td>

<td>{emp.Location}</td>

<td>{emp.Salary}</td>

</tr>

))}

</tbody>

</table>

</div>

}
const element=<EmployeeComponent></EmployeeComponent>

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

useContext Hook

In a typical React application, data is passed top-down (parent to child)


via props, but this can be difficult for certain types of props (e.g. locale
preference, UI theme) that are required by many components which are
Nested at different levels within an application. 

In this article, we will understand how we use Context to pass the data
between components at different nesting levels.

Lets take a look at one example. When an Employee is Logged into the
React application, we have a Nesting of Components which are making
our UI. 

They are App Component, Employee Component and Salary


Component. App Component has an Employee Object and this data is
needed by Employee Component and Salary Component in Order to
function.
Context provides a way to pass data through the component tree without
having to pass props down manually at every level.

Context provides a way to share values between components without


having to explicitly pass a prop through every level of the tree.

Context is primarily used when some data needs to be accessible by


many components at different nesting levels.

We have discussed this in the case of Class Components. We will


understand how do we use the context in the case of Function
Components. 

We will create three functional components. Named App Component,


Employee Component and Salary Component. 

Lets Call the Salary Component from Employee Component and Call
the Employee Component from App Component.

Call the App Component and render it to our DOM.


In App Component, lets create one employee state variable and a
function to update the employee data using useState hook and we will
initialize the state.

This employee object is needed by employee Component and by Salary


Component. 

Lets see how do we do that using Context in React. 

Lets create context object using React.createContext Method.

const EmployeeContext = React.createContext();

Copy

using the EmployeeContext object, we will pass the data from


AppComponent to the Employee Component and then from the
Employee Component to the Salary Component. 

Lets go to App Component, we modify the way how Employee


Component is being Called from App Component. 

So that Employee Component can receive the data from App Component
and pass that to the Child Components of Employee Component
implicitly. 

Every Context object comes with a Provider React component that


allows consuming components to subscribe to context changes.

Context Provider Accepts a value property to be passed to consuming


components that are descendants of this Provider.

<EmpContext.Provider value={empData}>

<Employee/>

</EmpContext.Provider>

Copy
Now this empData can be accessed in both Employee Component and
Salary Component using useContext hook in React. 

Lets go to Employee Component, get the Employee Context using


useContext hook. 

We can display the Employee details by reading from the context. 

We can do the Same in Salary Component as well. 

Save the Changes, navigate to the browser. We can see the Output. 

We can see that our employee data from App Component is accessed by
the 

Components which are placed at different Nesting Levels. 

One Level is from App Component to Employee Component and the


Second one is from Employee to Salary Component. 

import ReactDOM from "react-dom";

import React, { Component, useState, useContext } from "react";

const employeeContext=React.createContext();

function App(){

const [employee,setEmployee]=useState({Id:101,Name:'Pragim',

Location:'Bangalore',Salary:12345});

return(

<div>

<h2>Welcome to App Component...</h2>

<employeeContext.Provider value={employee}>

<Employee></Employee>
</employeeContext.Provider>

</div>

);

function Employee(){

let context=useContext(employeeContext);

return(

<div>

<h2>Welcome to Employee Component...</h2>

<p>

<label>Employee ID : <b>{context.Id}</b></label>

</p>

<p>

<label>Employee Name : <b>{context.Name}</b></label>

</p>

<Salary></Salary>

</div>

);

function Salary(){

let context=useContext(employeeContext);

return(

<div>
<h2>Welcome to Salary Component...</h2>

<p>

<label>Employee ID : <b>{context.Id}</b></label>

</p>

<p>

<label>Employee Salary : <b>{context.Salary}</b></label>

</p>

</div>

);

const element=<App></App>

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

You might also like