React Hooks
React Hooks
Hooks are the new feature introduced in the React 16.8 version. It allows
you to use state and other React features without writing a class. Hooks
are the functions which "hook into" React state and lifecycle features
from function components. It does not work inside classes.
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:
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.
AD
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:
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:
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.
Custom Hooks
AD
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;
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 ❯
Import useState
Example:
Initialize useState
Example:
function FavoriteColor() {
These names are variables that can be named anything you would like.
Read State
Example:
function FavoriteColor() {
Run Example »
Update State
Example:
function FavoriteColor() {
return (
<>
<button
type="button"
>Blue</button>
</>
root.render(<FavoriteColor />);
Run Example »
Example:
function Car() {
return (
<>
<h1>My {brand}</h1>
<p>
</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:
function Car() {
brand: "Ford",
model: "Mustang",
year: "1964",
color: "red"
});
return (
<>
<h1>My {car.brand}</h1>
<p>
</p>
</>
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Car />);
Run Example »
Example:
Use the JavaScript spread operator to update only the color of the car:
function Car() {
brand: "Ford",
model: "Mustang",
year: "1964",
color: "red"
});
setCar(previousState => {
return { ...previousState, color: "blue" }
});
return (
<>
<h1>My {car.brand}</h1>
<p>
</p>
<button
type="button"
onClick={updateColor}
>Blue</button>
</>
root.render(<Car />);
Run Example »
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(<function>, <dependency>)
Example:
function Timer() {
useEffect(() => {
setTimeout(() => {
}, 1000);
});
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.
1. No dependency passed:
useEffect(() => {
});
2. An empty array:
useEffect(() => {
}, []);
useEffect(() => {
}, [prop, state]);
So, to fix this issue, let's only run this effect on the initial render.
Example:
useEffect(() => {
setTimeout(() => {
}, 1000);
root.render(<Timer />);
Run Example »
Example:
function Counter() {
useEffect(() => {
return (
<>
<p>Count: {count}</p>
<p>Calculation: {calculation}</p>
</>
);
root.render(<Counter />);
Run Example »
w3schoolsCERTIFIED.2022
Get Certified!
Complete the React modules, do the exercises, take the exam and
become w3schools certified!!
$95 ENROLL
Effect Cleanup
Example:
function Timer() {
useEffect(() => {
}, 1000);
}, []);
root.render(<Timer />);
Run Example »
❮ PreviousNext ❯
React Context
The Problem
State should be held by the highest parent component in the stack that
requires access to the state.
Example:
function Component1() {
return (
<>
<h1>{`Hello ${user}!`}</h1>
</>
);
}
function Component2({ user }) {
return (
<>
<h1>Component 2</h1>
</>
);
return (
<>
<h1>Component 3</h1>
</>
);
return (
<>
<h1>Component 4</h1>
</>
);
}
function Component5({ user }) {
return (
<>
<h1>Component 5</h1>
</>
);
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
Create Context
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() {
return (
<UserContext.Provider value={user}>
<h1>{`Hello ${user}!`}</h1>
</UserContext.Provider>
);
Now, all components in this tree will have access to the user Context.
Use the useContext Hook
function Component5() {
<>
<h1>Component 5</h1>
</>
);
Full Example
Example:
function Component1() {
return (
<UserContext.Provider value={user}>
<h1>{`Hello ${user}!`}</h1>
</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() {
return (
<>
<h1>Component 5</h1>
</>
);
root.render(<Component1 />);
Run Example »
React useRef Hook
❮ PreviousNext ❯
It can be used to store a mutable value that does not cause a re-render
when updated.
Example:
function App() {
useEffect(() => {
count.current = count.current + 1;
});
return (
<>
<input
type="text"
value={inputValue}
/>
</>
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
Run Example »
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
Example:
inputElement.current.focus();
};
return (
<>
</>
);
root.render(<App />);
Run Example »
Example:
useEffect(() => {
previousInputValue.current = inputValue;
}, [inputValue]);
return (
<>
<input
type="text"
value={inputValue}
/>
</>
);
root.render(<App />);
Run Example »
If you find yourself keeping track of multiple pieces of state that rely on
complex logic, useReducer may be useful.
Syntax
useReducer(<reducer>, <initialState>)
Example:
const initialTodos = [
id: 1,
complete: false,
},
id: 2,
complete: false,
},
];
const reducer = (state, action) => {
switch (action.type) {
case "COMPLETE":
} else {
return todo;
});
default:
return state;
};
function Todos() {
};
return (
<>
{todos.map((todo) => (
<div key={todo.id}>
<label>
<input
type="checkbox"
checked={todo.complete}
/>
{todo.title}
</label>
</div>
))}
</>
);
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 ❯
It can be used to store a mutable value that does not cause a re-render
when updated.
Example:
function App() {
useEffect(() => {
count.current = count.current + 1;
});
return (
<>
<input
type="text"
value={inputValue}
</>
);
root.render(<App />);
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
Example:
Use useRef to focus the input:
function App() {
inputElement.current.focus();
};
return (
<>
</>
);
root.render(<App />);
Run Example »
Example:
Use useRef to keep track of previous state values:
function App() {
useEffect(() => {
previousInputValue.current = inputValue;
}, [inputValue]);
return (
<>
<input
type="text"
value={inputValue}
/>
</>
);
root.render(<App />);
Run Example »
❮ PreviousNext ❯
React useCallback Hook
❮ PreviousNext ❯
Problem
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
};
};
return (
<>
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
</div>
</>
);
};
root.render(<App />);
Todos.js
console.log("child render");
return (
<>
<h2>My Todos</h2>
})}
</>
);
};
Run Example »
w3schoolsCERTIFIED.2022
Get Certified!
Complete the React modules, do the exercises, take the exam and
become w3schools certified!!
$95 ENROLL
Solution
Example:
index.js
};
}, [todos]);
return (
<>
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
</div>
</>
);
};
root.render(<App />);
Todos.js
console.log("child render");
return (
<>
<h2>My Todos</h2>
})}
</>
);
};
Run Example »
React useMemo Hook
❮ PreviousNext ❯
Performance
The useMemo Hook can be used to keep expensive, resource intensive
functions from needlessly running.
When changing the count or adding a todo, you will notice a delay in
execution.
Example:
};
};
return (
<div>
<div>
<h2>My Todos</h2>
})}
</div>
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
<h2>Expensive Calculation</h2>
{calculation}
</div>
</div>
);
};
console.log("Calculating...");
num += 1;
return num;
};
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
Example:
};
return (
<div>
<div>
<h2>My Todos</h2>
})}
</div>
<hr />
<div>
Count: {count}
<button onClick={increment}>+</button>
<h2>Expensive Calculation</h2>
{calculation}
</div>
</div>
);
};
console.log("Calculating...");
for (let i = 0; i < 1000000000; i++) {
num += 1;
return num;
};
root.render(<App />);
Run Example »
React Custom Hooks
❮ PreviousNext ❯
Build a Hook
Use the JSONPlaceholder service to fetch fake "todo" items and display
the titles on the page:
Example:
index.js:
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/todos")
}, []);
return (
<>
{data &&
data.map((item) => {
})}
</>
);
};
root.render(<Home />);
Run Example »
useFetch.js:
useEffect(() => {
fetch(url)
}, [url]);
return [data];
};
return (
<>
{data &&
data.map((item) => {
})}
</>
);
};
root.render(<Home />);
Run Example »
Example Explained
Now we can reuse this custom Hook in any component to fetch data
from any URL.
Introduction to Hooks
1. Wrapper Hell
2. Huge Components
3. Confusing Classes
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.
Basic Hooks
• useState
• useEffect
• useContext
Additional Hooks
• useReducer
• useCallback
• useMemo
• useRef
• useImperativeHandle
• useLayoutEffect
• useDebugValue
constructor(props){
super(props);
this.state={
Name:''
}
changeName=(e)=>{
this.setState({Name:e.target.value});
render(){
return(
<div>
<p>
<label>Employee Name :
</label>
</p>
<p>
</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.
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.
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.
return(
<div>
<p>
<label>Employee Name :
onChange={changeName}></input>
</label>
</p>
<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.
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 see that our textbox is holding the value by default and we can
change if needed.
Our Employee Component is having one input element. Now lets say we
want to have another input using which we can enter Employee
Location.
const [location,setLocation]=useState();
Copy
<p>
<label>Employee Location :
onChange={changeEmployeeLocation}></input>
</label>
</p>
Copy
Save the changes, navigate to the browser. We can see the output.
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.
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.
function NewEmployee(){
const
[employee,setEmployeeData]=useState({Id:'',Name:'',Location:'',Salary:''
});
function changeEmployeeInfo(e){
setEmployeeData({...employee,[e.target.name]:e.target.value});
return(
<div>
<p>
<label>Employee ID :
</label>
</p>
<p>
<label>Employee Name :
onChange={changeEmployeeInfo}></input>
</label>
</p>
<p>
<label>Employee Location :
onChange={changeEmployeeInfo}></input>
</label>
</p>
<p>
<label>Employee Salary :
onChange={changeEmployeeInfo}></input>
</label>
</p>
<p>
</p>
<SalaryComponent salary={employee.Salary}
onSalaryChange={changeEmployeeInfo}></SalaryComponent>
</div>
const element=<NewEmployee></NewEmployee>
ReactDOM.render(element,document.getElementById("root"));
Copy
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.
What if, if want to write such code in the case of function components.
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.
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.
We can see the table but no data. Lets open developer tools, we can see
the status. It says that loading.
So where should we write the code which should get executed after our
DOM is ready.
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.
function EmployeeComponent(){
const [employees,setEmployees]=useState([]);
useEffect(()=>{
fetch("https://localhost:44306/api/Employee")
(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 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.
Lets Call the Salary Component from Employee Component and Call
the Employee Component from App Component.
Copy
So that Employee Component can receive the data from App Component
and pass that to the Child Components of Employee Component
implicitly.
<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.
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
const employeeContext=React.createContext();
function App(){
const [employee,setEmployee]=useState({Id:101,Name:'Pragim',
Location:'Bangalore',Salary:12345});
return(
<div>
<employeeContext.Provider value={employee}>
<Employee></Employee>
</employeeContext.Provider>
</div>
);
function Employee(){
let context=useContext(employeeContext);
return(
<div>
<p>
<label>Employee ID : <b>{context.Id}</b></label>
</p>
<p>
</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>
</p>
</div>
);
const element=<App></App>
ReactDOM.render(element,document.getElementById("root"));
Introduction to Hooks
1. Wrapper Hell
2. Huge Components
3. Confusing Classes
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.
Basic Hooks
• useState
• useEffect
• useContext
Additional Hooks
• useReducer
• useCallback
• useMemo
• useRef
• useImperativeHandle
• useLayoutEffect
• useDebugValue
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.
constructor(props){
super(props);
this.state={
Name:''
changeName=(e)=>{
this.setState({Name:e.target.value});
render(){
return(
<div>
<p>
<label>Employee Name :
</label>
</p>
<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.
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.
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>
<p>
<label>Employee Name :
onChange={changeName}></input>
</label>
</p>
<p>
</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.
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 see that our textbox is holding the value by default and we can
change if needed.
useState Hook
const [location,setLocation]=useState();
Copy
<p>
<label>Employee Location :
onChange={changeEmployeeLocation}></input>
</label>
</p>
Copy
Save the changes, navigate to the browser. We can see the output.
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.
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.
function NewEmployee(){
const
[employee,setEmployeeData]=useState({Id:'',Name:'',Location:'',Salary:''
});
function changeEmployeeInfo(e){
setEmployeeData({...employee,[e.target.name]:e.target.value});
return(
<div>
<p>
<label>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 :
onChange={changeEmployeeInfo}></input>
</label>
</p>
<p>
<label>Employee Salary :
onChange={changeEmployeeInfo}></input>
</label>
</p>
<p>
</p>
<SalaryComponent salary={employee.Salary}
onSalaryChange={changeEmployeeInfo}></SalaryComponent>
</div>
}
const element=<NewEmployee></NewEmployee>
ReactDOM.render(element,document.getElementById("root"));
Copy
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.
What if, if want to write such code in the case of function components.
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.
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.
We can see the table but no data. Lets open developer tools, we can see
the status. It says that loading.
So where should we write the code which should get executed after our
DOM is ready.
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.
function EmployeeComponent(){
const [employees,setEmployees]=useState([]);
useEffect(()=>{
fetch("https://localhost:44306/api/Employee")
.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 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.
Lets Call the Salary Component from Employee Component and Call
the Employee Component from App Component.
Copy
So that Employee Component can receive the data from App Component
and pass that to the Child Components of Employee Component
implicitly.
<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.
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
const employeeContext=React.createContext();
function App(){
const [employee,setEmployee]=useState({Id:101,Name:'Pragim',
Location:'Bangalore',Salary:12345});
return(
<div>
<employeeContext.Provider value={employee}>
<Employee></Employee>
</employeeContext.Provider>
</div>
);
function Employee(){
let context=useContext(employeeContext);
return(
<div>
<p>
<label>Employee ID : <b>{context.Id}</b></label>
</p>
<p>
</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>
</p>
</div>
);
const element=<App></App>
ReactDOM.render(element,document.getElementById("root"));
Introduction to Hooks
1. Wrapper Hell
2. Huge Components
3. Confusing Classes
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.
Basic Hooks
• useState
• useEffect
• useContext
Additional Hooks
• useReducer
• useCallback
• useMemo
• useRef
• useImperativeHandle
• useLayoutEffect
• useDebugValue
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.
constructor(props){
super(props);
this.state={
Name:''
changeName=(e)=>{
this.setState({Name:e.target.value});
render(){
return(
<div>
<p>
<label>Employee Name :
</label>
</p>
<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.
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.
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>
<p>
<label>Employee Name :
onChange={changeName}></input>
</label>
</p>
<p>
</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.
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 see that our textbox is holding the value by default and we can
change if needed.
useState Hook
const [location,setLocation]=useState();
Copy
<p>
<label>Employee Location :
onChange={changeEmployeeLocation}></input>
</label>
</p>
Copy
Save the changes, navigate to the browser. We can see the output.
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.
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.
function NewEmployee(){
const
[employee,setEmployeeData]=useState({Id:'',Name:'',Location:'',Salary:''
});
function changeEmployeeInfo(e){
setEmployeeData({...employee,[e.target.name]:e.target.value});
return(
<div>
<p>
<label>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 :
onChange={changeEmployeeInfo}></input>
</label>
</p>
<p>
<label>Employee Salary :
onChange={changeEmployeeInfo}></input>
</label>
</p>
<p>
</p>
<SalaryComponent salary={employee.Salary}
onSalaryChange={changeEmployeeInfo}></SalaryComponent>
</div>
}
const element=<NewEmployee></NewEmployee>
ReactDOM.render(element,document.getElementById("root"));
Copy
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.
What if, if want to write such code in the case of function components.
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.
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.
We can see the table but no data. Lets open developer tools, we can see
the status. It says that loading.
So where should we write the code which should get executed after our
DOM is ready.
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.
function EmployeeComponent(){
const [employees,setEmployees]=useState([]);
useEffect(()=>{
fetch("https://localhost:44306/api/Employee")
.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 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.
Lets Call the Salary Component from Employee Component and Call
the Employee Component from App Component.
Copy
So that Employee Component can receive the data from App Component
and pass that to the Child Components of Employee Component
implicitly.
<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.
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
const employeeContext=React.createContext();
function App(){
const [employee,setEmployee]=useState({Id:101,Name:'Pragim',
Location:'Bangalore',Salary:12345});
return(
<div>
<employeeContext.Provider value={employee}>
<Employee></Employee>
</employeeContext.Provider>
</div>
);
function Employee(){
let context=useContext(employeeContext);
return(
<div>
<p>
<label>Employee ID : <b>{context.Id}</b></label>
</p>
<p>
</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>
</p>
</div>
);
const element=<App></App>
ReactDOM.render(element,document.getElementById("root"));