Introduction
Hooks in React Js are functions that allow functional components to "hook into" React state and lifecycle features. It lets us use state and other React features without defining a class. Hooks don't work within classes; instead, they allow us to use React without the classes. What are Hooks in React Js? Hooks in React JS or React Hooks are a new feature in React 16.8 that enables developers to access React concepts like state, context, refs, and lifecycle events without having to use classes, which were previously exclusively available in class-based components.
To configure the React development environment(use the latest version of Node.js to run npx):
npx create-react-app exploring-hooks
Render props and HOCs(Higher-Order Components) are nearly obsolete thanks to the Hooks in React, which make sharing stateful functionality much more pleasant.
React comes pre-loaded with a number of hooks. UseState and useEffect are the most crucial.
In React, there are three ways to express components:
- class components
- functional components
- Hooks with functional components.
Need for React Hooks
A few of the reasons for the need for hooks in React JS are:-
- ‘This’ Keyword: The use of the 'this' keyword is for two reasons. The first is related to javascript rather than to React. To deal with classes, we must first learn how the javascript 'this' keyword works, which is considerably different from how it works in other languages. Although the concepts of props, state, and unidirectional data flow are easy to grasp, the use of the 'this' keyword may cause difficulties when implementing class components. Event handlers must also be bound to the class components. It has been found that classes do not concise efficiently, resulting in unreliable hot reloading, which can be done with Hooks.
- To reuse stateful logic: Higher-order components (HOC) and the render props pattern are two advanced concepts in React. Reusing stateful component functionality in React is not possible in any way. Though the usage of HOC and render properties patterns can fix this problem, it makes the code base inefficient and difficult to comprehend because components are wrapped in numerous other components to share functionality. Without modifying the component hierarchy, hooks allow us to exchange stateful functionality in a much better and cleaner way.
- Simplifying challenging scenarios: When developing components for complex scenarios such as data fetching and event subscription, it's likely that all related code is dispersed throughout many life cycle methods.
For example, data and fetching are often performed in ‘componentDidMount’ or ‘componentDidUpdate’, and event listeners are typically performed in ‘componentDidMount’ or ‘componentWillUnmount’. Instead of forcing a split based on the life-cycle method, hooks solve these issues. Hooks in React JS allow you to break down a single component into smaller functionalities depending on how the elements are connected.
Rules for Hooks in React JS
Hooks are JavaScript functions with two additional constraints:
-
Hooks are only called at the highest level. Hooks should not be called from within loops, conditions, or nested functions.
-
Hooks can only be called from React function components. Hooks should not be called from ordinary JavaScript functions. There's only one other location where you can call Hooks in React JS: by creating your own custom Hooks, which will be discussed in the latter part of this blog.
To enforce these constraints automatically, a linter plugin is provided. These constraints may appear restrictive or perplexing at first, but they are necessary for Hooks to function properly.
Check out the blog Rules of Hooks for a detailed explanation.
Declare State Variable
Declaring a state variable is as easy as running useState with an initial state value, such as useState (initialStateValue).
const declareStateVar = () => {
const [countVar] = useState(50)
return <div> The state variable is {countVar}.</div>
}

Output
Update State Variable
Updating the state variable means to run the updater function returned by the useState invocation: const [stateValue, updaterFunc] = useState(initialStateValue); which will update the state variable.
const updateStateVar = () => {
const [countAge, setAge] = useState(21)
const handleClick = () => setAge(countAge + 1)
return (
<div>
My age is {countAge}.
<div>
<button onClick = {handleClick}> Older Now! </button>
</div>
</div>
)
}

Output
On clicking the button ‘Older Now!’, the ‘age’ variable is incremented.

Output after updation
Multiple State Variables
Within a functional component, multiple state variables can be used and modified accordingly.
const multipleStateVar = () => {
const [countAge, setAge] = useState(21)
const [countSiblingNum, setSiblingNum] = useState(15)
const handleAge = () => setAge(countAge + 1)
const handleSibling = () => setSiblingNum(countSiblingNum + 1)
return (
<div>
<p>My age is {countAge}.</p>
<p>I have {countSiblingNum} siblings.</p>
<div>
<button onClick = {handleAge}> Older Now! </button>
<button onClick = {handleSibling}> Get Siblings!
</button>
</div>
</div>
)
}

Output
On clicking the buttons ‘Older Now!’ and ‘Get Siblings!’, the variables ‘countAge’ and ‘countSiblingNum’ get incremented.

Output after updation
Object State Variable
An object could be used as the first value supplied to useState instead of characters or numbers.
Because the object is replaced rather than merged, you must send the full object to the useState updater function.
// SetState (merge objects) VS useState (replace objects)
// Let's assume initial state is {name: "James"}
seState({age: 'unknown'})
// New state object will be {name: "James", age: "unknown"}
useStateUpdater({age: 'unknown'})
/*
New state object will be {age: "unknown"}, here, the initial object
is replaced
*/
A state object variable is used to keep track of multiple state objects.
const multipleStateObject = () => {
const [countState, setState] = useState({age: 21, siblingNum: 3})
const handleClick = val =>
setState({
...countState,
[val] : countState[val] + 1
})
const {age, siblingNum} = countState
return (
<div>
<p>My age is {age}.</p>
<p>I have {siblingNum} siblings.</p>
<div>
<button onClick = {handleClick.bind(null, 'age' )}>
Older Now! </button>
<button onClick = {handleClick.bind(null, 'siblingNum'
)}> Get Siblings!
</button>
</div>
</div>
)
}

Output
On clicking the buttons ‘Older Now!’ and ‘Get Siblings!’, the variables ‘age’ and ‘siblingNum’ get incremented.

Output after updation
Basic Hooks in React JS
Let’s explore some basic Hooks in React JS,
-
useState
You can create a new state variable with the useState() API, and it also allows you to update the variable's value.
useState() accepts an initial value for the state variable and returns an Array that contains both the state variable and a function that may be used to alter it later.
Only functional components should utilize ‘useState’. If we require an internal state but don't want to add more complex logic like lifecycle methods, ‘useState’ is the way to go. -
useEffect
From the birth until the death of a React component, classes have life cycle methods that conduct a series of activities. Mounting, updating, and unmounting are all processes that any component goes through. To perform side effects in class-components, we use cycle methods like componentDidMount(), componentDidUpdate(), componentWillUnmount(), and so on. Side effects include processes like data fetching, subscriptions, and manually modifying the DOM from React components. componentDidMount() and componentDidUpdate() are added to the following code to modify the document title when the input name changes.
export default class extends React.Component{
constructor(props){
super(props);
this.state = {name:'helloWorld'}
}
componentDidMount(){
document.title = this.state.name;
}
componentDidUpdate(){
document.title = this.state.name;
}
handleNameChange(){
this.setState({name: e.target.value});
}
render(){
return(
<section>
<input value={this.state.name}
onChange={this.handleNameChange}
/>
<text>{this.state.name}</text>
</section>
);
}
}
The render() method has no side effects because it can affect the other components. So, how do we implement that as a function component? It's what the ‘useEffect’ hook is for. After the first render and after each update, ‘useEffect’ is called. ‘useEffect’ is used multiple times.
import react, {useState, useEffect} from 'react';
export default function Application{
const[state, setState] = useState('helloWorld');
useEffect(() => {
document.title = name
});
function handleNameChange(e){
setState(e.target.value);
}
return(
<div>
<input value={name}
onChange={handleNameChange}
/>
<text>{name}</text>
</div>
);
-
useContext
Context API provides a clean and simple approach to transfer state between components without using React to give props. The useContext hook takes the context object that React returns as a value React.createContext().
Custom Hooks
A custom Hook is a JavaScript function that begins with the word "use" and can invoke other Hooks.
The purpose of custom Hooks is to prevent logic from being duplicated. Custom Hooks allow you to reuse stateful functionality across components without having to add extra components. The logic for the useNameInput() and useDocumentTitle() routines is separated in this code. They've been renamed Hooks. Custom Hooks are now completely autonomous of the state. As a result, custom Hooks can now be used many times in a single component.
import React, {useState, useEffect} from 'react';
export default function Application(){
const name = useNameInput('helloWorld');
useDocumentTitle(name.value);
return(
<div>
<input {...name}/>
<text>{name.value}</text>
</div>
);
}
function useNameInput(initialValue){
const [value, setValue] = useState(initialValue);
function handleNameChange(e){
setValue(e.target.value);
}
return{
value,
onChange: handleNameChange
}
}
function useDocumentTitle(title){
useEffect(()=>{document.title = title});
}
Check out Advantages of React JS here.
Frequently Asked Questions
Why do you mean by Hooks in React JS?
A hook is an API that lets you hook into React state and other features in your functional components without having to develop a class only to get access to a state or a life-cycle event. This also implies that we won't have to rewrite the functional component into a class component if we need to access those features later We can use React's built-in hooks to access the common functionality, but we can also write our own custom hooks.
The ‘useState’ Hook in React JS is not used immediately. Explain.
If you're wondering why useState/setState isn't updating right away, it's because they're just queues. React useState and setState don't change the state object directly; instead, they build queues to improve efficiency, which is why the changes don't show up right away.
Is it possible to render props with Hooks in React JS?
There's no reason to do so. Earlier componentDidMount() was used but now useEffect can be used instead of it. Let’s look at an example.
import React, {useState, useEffect} form "react"
export default function DataLoader(props){
const [data, setData] = useState([]);
useEffect (() => {
fetch("http://localhost:3001/links/")
.then(response => response.json())
.then(data => setData(data))
}, []);
return props.render(data)
}
Conclusion
In this blog, we went over the fundamentals of Hooks in React JS and discussed briefly types of hooks in React JS and why React introduced them. Then, using Hooks, create function components and compare them to class components. The useState, useEffect, useContext, and custom Hooks and their rules are mostly explored. This blog, I believe, will be beneficial to those who want to learn more about Hooks in React JS.
Recommended Reading
Enroll in our Advance Front-end Web Development Course- React.js to deeply understand the concept of Hooks in React JS in Web Development with real-life projects to work on. You can also check out some of the Guided Paths on topics such as Data Structure and Algorithms along with some Interview Experiences and Contests brought to you by industry experts only on CodeStudio.
Credits: GIPHY
Happy Developing!