---
title: "Rules of React Hooks | CoderPad"
description: "Since the introduction of React Hooks in v16.8.0, React Hooks is widely used by developers who prefer to write functional components to class components. In this short but detailed article, you will be taught the rules of React Hooks to improve your web development skills."
canonical: "https://coderpad.io/blog/development/rules-of-react-hooks/"
last_modified: "2026-04-15 16:21:08"
---
[Back to blog](https://coderpad.io/blog/)

# Rules of React Hooks

October 11, 2022 5 Minute Read

By Joel Olawanle

[Development](https://coderpad.io/blog/development/)

Over the years, React has become one of the most used and loved JavaScript frameworks in the world.

React is a component-based library with two standard ways of defining its components:

1. As class components
2. As functional components

You can use these two methods to achieve the same outcome but with different syntax.

The class components are ES6 classes that return JSX and necessitate a React class extension, while the functional components are ES6 functions that return a React element as JSX. It is essential to know that they both return JSX (JavaScript XML), allowing us to write HTML elements in JavaScript. React then takes this JSX and places the elements in the DOM.

[![A comparison between class based and functional component returning JSX with a heading of "Hello World"](https://coderpad.io/wp-content/uploads/2022/10/img_634478f033db9.png)](https://coderpad.io/wp-content/uploads/2022/10/img_634478f033db9.png)

Before the introduction of React Hooks in version 16.8, the class component had always been the superior method of creating a component when you need to work with state (data management) and handle lifecycle methods, like component mounts, renders, updates, and unmounts.

In those days, you could only use the functional component to render a user interface. With the introduction of Hooks in 2019, functional components gained the superpowers that class components already possessed, which meant that you could work with state and handle lifecycle methods.

## What are React Hooks?

React Hooks help us Hook into React features in functional components. These features include state and side effects (similar to lifecycle methods).

The two most common React Hooks are`useState()`and`useEffect()`. The`useState()`Hook acts as a store that allows it to use state variables and update them. You can even destructure the`useState()`Hook to hold the state variable and update function separately. It also allows you to pass an initial value directly into the Hook.

[![A comparison of how the class and functional components work with states and output state values within JSX.](https://coderpad.io/wp-content/uploads/2022/10/img_634478f1f18be.png)](https://coderpad.io/wp-content/uploads/2022/10/img_634478f1f18be.png)

With the`useEffect()`Hook, you can efficiently perform side effects (similar to lifecycle methods) such as when your application mounts/renders or when a value updates. You can read about [`useEffect()`, and its rules here](https://coderpad.io/blog/development/rules-of-reacts-useeffect/).

Understanding the rules that guide the operation of React Hooks will help you and your team avoid some unnecessary errors and bugs.

## The two rules of React Hooks

Two significant rules need to be followed when working with Hooks. These rules are essential to maintain order, avoid unnecessary bugs, and help us write clean code. These rules are:

1. Only call Hooks at the top level
2. Only call Hooks from React functional components or other Hooks

### Only call Hooks at the top level of your functional component

The top level of a functional component is the base of your function body before you return your JSX elements. This is where you can call all your Hooks, so React can preserve and take note of the order in which these Hooks are called.

[![A display of the top level of functional components and an example of the type of Hooks that can go into it.](https://coderpad.io/wp-content/uploads/2022/10/img_634478f3070bf.png)](https://coderpad.io/wp-content/uploads/2022/10/img_634478f3070bf.png)

Calling your Hooks at the top of the function means you must not be calling them within loops, conditions, and nested functions.

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

const App = () => {
    // ![✅](https://coderpad.io/assets/emoji/2705.svg) - correct
    const [todos, setTodos] = useState([]);
   
    // ![❌](https://coderpad.io/assets/emoji/274c.svg) - Breaks the call order
    if (todos) {
        const [count, setSetcount] = useState(todos.length);
    }

    // ![❌](https://coderpad.io/assets/emoji/274c.svg) - Breaks the call order
    todos.forEach(todo => {
        useEffect(() => {
            console.log(todos);
        });
    });
   
    // ![✅](https://coderpad.io/assets/emoji/2705.svg) - correct
    useEffect(() => {
        console.log(todos);
    });

    return (
        // ...
    );
};

export default App;Code language: JavaScript (javascript)
```

It is necessary to call Hooks at the top level of your functional component to ensure that every time your component renders, these Hooks are called in the same order. The call order is essential for Hooks to work correctly.

For example, when you consider the code above, it uses the value of the`todos`state to decide whether to call the second and third Hook. When the condition fails, or something happens to the loop, it breaks the order. React will then have a hard time figuring out how to preserve the state of your component.

This is what React does when you make use of Hooks. It identifies the order in which the Hooks are used at the initial render, then in subsequent renders, React will be able to preserve the state of your component.

A perfect example to explain this would be this: you have a functional component with a state that holds the user’s data, such as the`firstName`and`age`. Then you get the`lastName`from another state. You now use the`useEffect()`Hook to update your page title to reflect both names.

```
const App = () => {
    // 1. Use the user state variable
    const [user, setUser] = useState({
        firstName: 'John',
        age: 20,
    });

    // 2. Use the lastName state variable
    const [lastName, setLastName] = useState('Doe');

    // 3. Use an effect for updating the user details and updating the title
    useEffect(() => {
        document.title = user.firstName + ' ' + lastName;
    });

    // ...

};Code language: JavaScript (javascript)
```

This example will always work because the order is constant, and nothing affects the order on every render:

```
// First render
// ---
// 1. Initialize the name state variable with an object containing name and age
useState({ firstName: 'John', age: 20 })
// 2. Initialize the lastName state variable with 'Doe'
useState('Doe')
// 3. Add an effect to update the title
useEffect()

// Second render
// ---
// 1. Read the user state variable (the argument is ignored)
useState({ firstName: 'John', age: 20 })
// 2. Read the lastName state variable (the argument is ignored)
useState('Doe')
// 3. Replace the effect for updating the title
useEffect()Code language: JavaScript (javascript)
```

But in a situation where you put one of these Hooks in a condition, the order will break when the condition returns`false`, leading to bugs:

```
![❌](https://coderpad.io/assets/emoji/274c.svg) - Breaks the call order
if(user.firstName){
    const [lastName, setLastName] = useState('Doe');
}Code language: JavaScript (javascript)
```

The condition will be`true`on the first render, making React store the Hook’s order. If it returns`false`in the next render, it then affects any other Hook declared after this one and returns the wrong state for that Hook.

If you must have a condition, then you can take this Hook out of the condition statement and use the state update function (`setLastName()`in our example) instead:

```
const [lastName, setLastName] = useState('');

if(users.firstName && !lastName){
    setLastName('Doe');
}Code language: JavaScript (javascript)
```

If it is a`useEffect()`Hook, you can write your conditions or nested functions or loops within the Hook itself:

```
useEffect(() => {
    if (condition) {
    // statement
    }
});Code language: JavaScript (javascript)
```

### Only call Hooks from React functions

A second rule is that Hooks should only be used and called in React functional components or custom Hooks, not regular JavaScript functions or React class components.

The example below is invalid because it is a standard JavaScript function. Even if you decided to import`useState()`, it won’t work because it’s not a React component or custom Hook.

```
import { useState } = "react";

function getName() {
    const [name, setName] = useState("John Doe");
    return name;
}
document.getElementById("user-name").innerHTML = getName();Code language: JavaScript (javascript)
```

To create a custom Hook, you simply create a JavaScript function where the function’s name begins with`use`. From there, you can use it to call other Hooks. For example, here’s an implementation of the custom Hook`useMyName`:

```
export default function useMyName(name) {
    const [state, setState] = useState(value);
   
    useEffect(() => {
    // ...
    });
   
    return anyThing;
}Code language: JavaScript (javascript)
```

You can learn more about custom Hooks and how to create yours in the [official React documentation](https://reactjs.org/docs/hooks-custom.html).

## Enforcing Rules With ESLint Plug-in

Knowing these rules is not enough; you must enforce and abide by them too. It is easy to follow these rules when working alone on a project, but when working in a team or on an external project, it is a good idea to devise ways to check if these rules are followed to reduce the chance of introducing bugs into the code.

React released an ESLint plugin called [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks) to help enforce both React Hook rules. If you want to try it out, you can do so by installing it with the following command:

```
npm install eslint-plugin-react-hooks --save-dev
```

```
// Your ESLint configuration
{
    "plugins": [// ...
    "react-hooks"
    ],
    "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks
    "react-hooks/exhaustive-deps": "warn" // Checks effect dependencies
    }
}Code language: JSON / JSON with Comments (json)
```

![ℹ️](https://coderpad.io/assets/emoji/2139.svg) If you installed React via [Create React App](https://reactjs.org/docs/create-a-new-react-app.html#create-react-app), then this plugin is installed by default, and you will notice it will always flag situations where you don’t abide by the rules with errors like this:

[![An error that appears when you break one of the rules. This occurs when you make use of the React Hooks eslint plugin.](https://coderpad.io/wp-content/uploads/2022/10/img_634478f3b2d2d.png)](https://coderpad.io/wp-content/uploads/2022/10/img_634478f3b2d2d.png)

## Try it out for yourself!

You can take a turn implementing React Hook rules for yourself:

## Wrapping up

In this article, you have learned what Hooks are, why and when you should use Hooks, and what they can do. You’ve also learned that the order in which your Hooks are called is vital to React.

You should always call your Hooks at the top level of your components. Furthermore, you can use these Hooks only in React functional components and callback Hooks, not in JavaScript functions.

Thanks for reading, and have fun coding!

I’m Joel Olawanle, a front-end developer and technical writer interested in making the web accessible to everyone by always looking for ways to give back to the tech community. Follow me and connect with me on [Twitter](https://twitter.com/olawanle_joel).

## Subscribe for more CoderPad insights

## Trending Articles

Previous slide Next slide [Development

## What is Prompt Engineering?

Introducing AI tools such as ChatGPT and Bard helps increase the efficiency of tasks such as data generation, code generation and completion, text summarization, etc. How were these AI tools trained to answer almost every question you ask them? The answer, prompt engineering, is discussed in this blog post.

Read the post](https://coderpad.io/blog/development/what-is-prompt-engineering/) [Development

## A Guide To Using React’s useCallback() Hook

Are you looking to optimize your React applications? Have you heard of the useCallback hook? useCallback is a powerful React hook that helps you optimize your application by preventing unnecessary re-renders. In this post, we'll dive into React's useCallback() hook, define referential equality and callback functions and how to tie it all together.

Read the post](https://coderpad.io/blog/development/a-guide-to-using-reacts-usecallback-hook/) [Development

## MySQL vs. PostgreSQL: How Do They Compare?

A database is a convenient tool that allows users to access information, maintain records, and apply commonly used operations, such as insertion, modification, deletion, and data organization. Learn about MySQL vs PostgreSQL, their features, advantages, and disadvantages. Finally, check out which one is the best choice for you.

Read the post](https://coderpad.io/blog/development/mysql-vs-postgresql-how-do-they-compare/) [Development

## PostgreSQL LIKE Operator: A Detailed Guide

When using databases, searching for values that match a given pattern is a familiar necessity. Learn how you can retrieve entries with queries including a particular string using Postgres LIKE operator.

Read the post](https://coderpad.io/blog/development/postgresql-like-operator-a-detailed-guide/) [Development

## How To Use DataProvider In TestNG With Examples

When it comes to testing there are many tools and techniques available. In this post, we'll discuss how to use DataProvider with TestNG.

Read the post](https://coderpad.io/blog/development/how-to-use-dataprovider-in-testng-with-examples/) [Development

## How To Get Up And Running With Django Migrations: A Guide

Django migrations are a way of handling the application of changes to a database schema. By following the steps outlined in this guide, you can easily set up and use migrations in your Django projects.

Read the post](https://coderpad.io/blog/development/how-to-get-up-and-running-with-django-migrations-a-guide/) [Development

## Writing A Parameterized Test In JUnit With Examples

A JUnit parameterized test allows you to decouple data from structure, generating cleaner and more reliable tests. Learn more in this guide.

Read the post](https://coderpad.io/blog/development/writing-a-parameterized-test-in-junit-with-examples/) [Development

## How To Use Assert In JUnit With Examples

The JUnit Assert class is what you use to write unit testing assertions in JUnit. Learn more about it in this guide, full of examples.

Read the post](https://coderpad.io/blog/development/how-to-use-assert-in-junit-with-examples/) [Development

## A Simple Guide To TypeORM: What It Is And How To Use It

Considering current languages have object-oriented programming features, most database management systems are based on the relational model, with tables instead of objects. For these reasons, mapping relational objects is very important in development. In this article, you will learn what TypeORM, one of the main tools used today, is.

Read the post](https://coderpad.io/blog/development/a-simple-guide-to-typeorm-what-it-is-and-how-to-use-it/) [Development

## Using PreparedStatement in JDBC With Examples

In this post, we'll see why and how to work with JDBC and PreparedStatement. We will also learn along with examples using code.

Read the post](https://coderpad.io/blog/development/using-preparedstatement-in-jdbc-with-examples/) [Development

## React vs React Native: The Differences Explained

React and React Native are similar in that they both allow web developers to build applications based on the unique concept of components. But the two frameworks do this in radically different ways. In this post, we cover the key differences between react and react native frameworks, implementation, and which is an appropriate choice.

Read the post](https://coderpad.io/blog/development/react-vs-react-native-the-differences-explained/) [Development

## Logging in Django

The most challenging part of fixing a problem is identifying it. Unfortunately, this statement is exceptionally true when it comes to debugging. Learn how to use the power of logging into your Django applications to improve your debug process in this article.

Read the post](https://coderpad.io/blog/development/logging-in-django/)

## Hire with confidence.

See why engineering teams trust CoderPad to evaluate developers with realistic, AI-ready hiring workflows.

[Request a demo](https://coderpad.io/sales/)
