Table of contents
1.
Introduction 
2.
What are Hooks in React Js? 
3.
What is a Hook?
4.
When to use Hooks in React JS?
5.
Need for React Hooks
6.
Types of React Hooks
6.1.
1. useState
6.2.
2. useEffect
6.3.
3. useContext
6.4.
4. useReducer
6.5.
5. useCallback
6.6.
6. useMemo
6.7.
7. useRef
6.8.
8. useImperativeHandle
7.
Rules for Hooks in React JS
8.
Prerequisites for Hooks in React Js
9.
React Hooks Installation
10.
Basic Hooks in React JS 
10.1.
useState
10.2.
useEffect
10.3.
useContext
11.
Custom Hooks in React Js 
12.
Additional Hooks in React Js
12.1.
useMemo
12.1.1.
Example
12.2.
useId
12.2.1.
Example
12.3.
useRef
12.3.1.
Example
13.
Difference Between Hooks and Class Components
14.
Frequently Asked Questions
14.1.
What are Hooks used for?
14.2.
Why create a React Hook?
14.3.
How many types of Hooks are there in Reactjs?
14.4.
What is the difference between a hook and a function?
14.5.
Are hooks important in React?
15.
Conclusion
Last Updated: Jan 13, 2025
Easy

React Hooks

Author Sneha Mallik
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

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. 

hooks in react js

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.

What is a Hook?

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.

When to use Hooks in React JS?

Hooks in React JS are used to manage state and side effects in functional components, allowing you to use React features without writing class components. We can use hooks in React JS when we have to:

1. Manage State:

  • Use useState to add state to functional components.
  • Example: Tracking form inputs or counters.

2. Handle Side Effects:

  • Use useEffect for side effects like data fetching or DOM manipulation.
  • Replaces lifecycle methods from class components.

3. Custom Logic:

  • Create custom hooks to encapsulate and reuse stateful logic.
  • Keeps components clean and avoids code duplication.

4. Context Management:

  • Use useContext to access and manage context values.
  • Ideal for sharing data like themes or authentication status across 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.

Types of React Hooks

In React, several types of hooks provide different functionalities for managing state, side effects, and context in functional components. Here are the main types of React hooks:

1. useState

The useState hook manages state in a functional component. It initializes state and provides a function to update it.

Example:

import React, { useState } from 'react';

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

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default Counter;

 

Explanation: useState(0) initializes the count state with 0. setCount updates the state when the button is clicked.

2. useEffect

The useEffect hook manages side effects, such as fetching data, subscriptions, or updating the DOM.

Example:

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

function DataFetcher() {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then((response) => response.json())
      .then((data) => setData(data));
  }, []);

  return (
    <ul>
      {data.map((item) => (
        <li key={item.id}>{item.title}</li>
      ))}
    </ul>
  );
}

export default DataFetcher;

 

Explanation: The useEffect runs after the component renders. The empty dependency array [] ensures it runs only once.

3. useContext

The useContext hook accesses context values provided by a React.Context provider.

Example:

import React, { createContext, useContext } from 'react';

const ThemeContext = createContext('light');

function ThemeDisplay() {
  const theme = useContext(ThemeContext);

  return <p>Current theme: {theme}</p>;
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemeDisplay />
    </ThemeContext.Provider>
  );
}

export default App;

 

Explanation: useContext(ThemeContext) accesses the value from the nearest ThemeContext.Provider.

4. useReducer

The useReducer hook manages complex state logic using a reducer function.

Example:

import React, { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </div>
  );
}

export default Counter;

 

Explanation: useReducer uses a reducer function to update state based on actions.

5. useCallback

The useCallback hook memoizes a function, preventing unnecessary re-creations.

Example:

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

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

  const increment = useCallback(() => {
    setCount((prevCount) => prevCount + 1);
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

export default Counter;

 

Explanation: The increment function is memoized, so it doesn't get recreated on every render.

6. useMemo

The useMemo hook memoizes a computed value to optimize performance.

Example:

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

function ExpensiveComputation({ num }) {
  const result = useMemo(() => {
    console.log('Computing...');
    return num * 10;
  }, [num]);

  return <p>Result: {result}</p>;
}

export default ExpensiveComputation;

 

Explanation: The computation runs only when num changes, saving resources.

7. useRef

The useRef hook creates a mutable reference that persists across renders.

Example:

import React, { useRef } from 'react';

function FocusInput() {
  const inputRef = useRef(null);

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}

export default FocusInput;

 

Explanation: useRef stores the reference to the input element for direct DOM manipulation.

8. useImperativeHandle

The useImperativeHandle customizes the behavior of a ref passed to a child component.

Example:

import React, { useImperativeHandle, useRef, forwardRef } from 'react';

const CustomInput = forwardRef((props, ref) => {
  const inputRef = useRef();

  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));

  return <input ref={inputRef} type="text" />;
});

function App() {
  const inputRef = useRef();

  return (
    <div>
      <CustomInput ref={inputRef} />
      <button onClick={() => inputRef.current.focus()}>Focus Input</button>
    </div>
  );
}

export default App;

Explanation: useImperativeHandle exposes specific methods (focus) of the child component to the parent.

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.

Prerequisites for Hooks in React Js

We must be aware of the prerequisites of React Hooks before installing it.

  • Knowledge of Javascript fundamentals
     
  • Basic knowledge of React.js
     
  • The functional component of React
     
  • React state and props
     
  • React component lifecycle

React Hooks Installation

Let us look at the installation of React Hooks.

Step 1: For using React Hooks, we must have NPM and Node installed in our machine, and we must create a basic React app tool for running web applications.

Step 2: We will install  React js and React-dom for running and executing hooks.

$ npm install react@16.8.0-alpha.1 --save  
$ npm install react-dom@16.8.0-alpha.1 --save  

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 in React Js 

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.

Additional Hooks in React Js

The following are some additional hooks available in React:-

useMemo

The useMemo hook is used to memoize the result of an expensive computation so that it is not recalculated every on every render. This improves the performance by preventing unnecessary calculations when the dependencies of the computation have not changed.

Example

import React, { useState, useMemo } from 'react';
function FibonacciCalculator({ n }) {
 const calculateFibonacci = (num) => {
   if (num <= 1) return num;
   return calculateFibonacci(num - 1) + calculateFibonacci(num - 2);
 };
 const fibonacciResult = useMemo(() => calculateFibonacci(n), [n]);
 return (
   <div>
     <p>Fibonacci({n}) = {fibonacciResult}</p>
   </div>
 );
}

 

In this example, the calculateFibonacci function is cached, and the value of fibonacciResult is only recalculated when n changes.

useId

The useId is hook is used for generating unique IDs that can be passed to accessibility attributes such as “aria-describedby”. You should not use it for generating keys in a list, as the returned value from useId is not guaranteed to be the same on every re-render.

Example

import { useId } from 'react';
function PasswordField() {
 const passwordHintId = useId();
 <>
  <input type="password" aria-describedby={passwordHintId} />
  <p id={passwordHintId}>
 </>
}

 

In this example, we use the unique ID generated by the useID hook for the “aria-describedby” value. This is an accessibility attribute which is used to establish a relationship between widgets or groups and the text that describes them.

useRef

The useRef hook is used for creating persistent reference values that are not needed for rendering. Unlike state variables, the value of a useRef reference doesn't cause rerenders. This makes it useful for interacting with DOM elements.

Example

import React, { useRef, useEffect } from 'react';
function FocusInput() {
 const inputRef = useRef(null);
 useEffect(() => {
   inputRef.current.focus();
 }, []);
 return <input ref={inputRef} />;
}

 

In this example, we use the inputRef reference value to interact with the focus() DOM method. The focus() method is called on the initial render using the useEffect hook, which makes the focus state of the input element active.

Difference Between Hooks and Class Components

FeatureHooks (Functional Components)Class Components
SyntaxUses functions with hooks (e.g., useState, useEffect).Uses ES6 classes with render() method.
State ManagementuseState hook to manage state.State is managed using this.state and this.setState().
Side EffectsuseEffect hook to handle side effects.Lifecycle methods like componentDidMount, componentDidUpdate, componentWillUnmount.
ContextuseContext hook to consume context.contextType or Context.Consumer to access context.
Code StructureSimpler and more concise with functional components.More verbose, with class methods and this keyword.
Lifecycle MethodsNo lifecycle methods; use useEffect for similar functionality.Use lifecycle methods (e.g., componentDidMount, componentDidUpdate).
Performance OptimizationuseMemo and useCallback for optimization.Use PureComponent or shouldComponentUpdate for optimization.
Ref HandlinguseRef for accessing DOM elements and storing mutable values.React.createRef() or callback refs for accessing DOM elements.
State LogicState logic can be shared using custom hooks.State logic is often duplicated or requires higher-order components.
ReusabilityHooks promote reusability and composability of logic.Reusability typically achieved through higher-order components or render props.
Type CheckingEasier to use with TypeScript or Flow for functional components.Class components can also use TypeScript or Flow for type checking.

Frequently Asked Questions

What are Hooks used for?

Hooks are used to add state, lifecycle, and other React features to functional components, enabling them to manage logic and side effects efficiently.

Why create a React Hook?

Creating custom React hooks helps encapsulate reusable logic, making components cleaner, modular, and easier to maintain while avoiding duplication across the application.

How many types of Hooks are there in Reactjs?

ReactJS provides several built-in hooks that allow developers to add state and other React features to functional components. Some of the commonly used hooks are useState, useEffect, useContext, useReducer, useCallback, useMemo, useRef, useLayoutEffect, useImperativeHandle, etc.

What is the difference between a hook and a function?

Functions and hooks in React refer to different concepts, but they are related because hooks are a type of function introduced in React to allow developers to use different React features in functional components.

Are hooks important in React?

Yes, Hooks are important in React as they enable functional components in React. Custom hooks increase code reusability. Hooks also simplify the database and improves the readability of the code.

Conclusion

In this blog, we learned about React Hooks and discussed briefly the 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 ReactJS.

Recommended Reading -

You can also consider our React Js Course to give your career an edge over others.

Happy Developing!

Live masterclass