React Hooks

In the last lesson you learned about React Form Validation. In that lesson, you already used useState to store form values. Now we will understand why React has hooks and where they fit in a component.

Why do we need hooks?

In React, a component often has to remember something.

Think about a login form. The user types a username and password. React has to keep those values somewhere so the component can use them when the user clicks the Login button.

Before hooks, these things were mostly done with class components. Class components worked, but they added extra code like this, constructors, and lifecycle methods.

Hooks made this easier.

When we use hooks, function components can also remember values and work with React features without becoming class components.

So in simple words:

Hooks are special React functions that give extra powers to function components.

Start with one example

Let us use one example in this lesson: a small login form.

In a login form:

  • First, the user types the username.
  • Then the user types the password.
  • After that, the user clicks the Login button.
  • Then, if the details are correct, the app can redirect the user to the dashboard page.

For this flow, React has to remember what the user typed. That is where hooks start helping.

What is a hook?

A hook is a function from React whose name starts with use.

Examples:

  • useState
  • useEffect
  • useRef
  • useContext
  • useMemo
  • useCallback

The use prefix is important. It tells React and React tools that this function follows hook rules.

Simple meaning

When we call a hook inside a function component, we are asking React to give that component one extra ability.

For now, do not try to master every hook from this page. This page is only a map. The next lessons explain each hook properly.

Hooks in the login form

These are only quick examples. The next lessons will explain each hook slowly.

useState remembers what the user typed

In a login form, the username input should remember what the user typed.

import { useState } from "react";
function LoginForm() {
const [username, setUsername] = useState("");
return (
<form>
<label htmlFor="username">Username</label>
<input
id="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</form>
);
}

Let us understand what happens in steps.

  • First, useState("") creates a state value.
  • username holds the current value.
  • setUsername is the function used to change that value.
  • When the user types in the input, onChange runs.
  • Then setUsername(e.target.value) saves the latest typed value in React state.

useEffect runs work after React updates

After the user logs in successfully, the app may need to redirect the user to the dashboard page.

import { useState, useEffect } from "react";
function LoginForm() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(() => {
if (isLoggedIn) {
// redirect user after login
}
}, [isLoggedIn]);
return <button onClick={() => setIsLoggedIn(true)}>Login</button>;
}

Here is the flow:

  • First, the user clicks the Login button.
  • Then setIsLoggedIn(true) changes the state.
  • After that, React updates the component.
  • Then useEffect runs and checks isLoggedIn.
  • If isLoggedIn is true, the app can redirect the user.

useRef points to the real input

In a login form, we may want the username input to get focus automatically when the form opens.

import { useEffect, useRef } from "react";
function LoginForm() {
const usernameInputRef = useRef(null);
useEffect(() => {
usernameInputRef.current.focus();
}, []);
return (
<form>
<label htmlFor="username">Username</label>
<input id="username" ref={usernameInputRef} />
</form>
);
}

Let us understand what happens in steps.

  • First, useRef(null) creates a ref object.
  • Then we connect that ref to the input using ref={usernameInputRef}.
  • After React displays the input on the screen, the real input element is stored in usernameInputRef.current.
  • Then the effect runs and focuses the username input.

Common hooks in one place

You do not need to memorize every hook today. Just know what job each hook usually does.

Hook Simple use
useState Stores a value and re-renders the component when that value changes
useEffect Runs code after React updates the screen
useRef Stores a value or DOM element reference without causing re-render
useContext Reads shared data without passing props through every level
useMemo Remembers a calculated value so React does not calculate it again unnecessarily
useCallback Remembers a function so React does not create a new function unnecessarily

In most beginner React work, you will use useState and useEffect the most. The other hooks become useful when the app grows.

Hooks have rules

Hooks are easy to call, but we cannot call them anywhere we want.

There are two main rules.

  • Call hooks only at the top level of a React function component.
  • Call hooks only from React function components or from custom hooks.

This means we should not call hooks inside if, for, while, or normal helper functions.

function LoginForm({ showPassword }) {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
if (!showPassword) {
return <p>Password field is hidden</p>;
}
return (
<form>
<input value={username} onChange={(e) => setUsername(e.target.value)} />
<input value={password} onChange={(e) => setPassword(e.target.value)} />
</form>
);
}

In this example, both hooks are called before the if.

That is good because:

  • First render, React sees the first hook and second hook.
  • Next render, React again sees the first hook and second hook.
  • The order stays the same.
  • So React can connect each state value to the correct hook.

Do not change hook order

React tracks hooks by the order in which they are called. If a hook runs in one render but is skipped in another render, React can connect the wrong state to the wrong hook.

Custom hooks

A custom hook is a hook we create ourselves.

Its name also starts with use.

Suppose our login form needs to store form fields in many places. Later, we can move some repeated state logic into a custom hook.

import { useState } from "react";
function useLoginFields() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
return {
username,
password,
setUsername,
setPassword,
};
}

Now any login component can call useLoginFields() and get the same field logic.

Important thing:

  • A custom hook reuses logic.
  • It does not automatically share the same state between components.
  • Each component that calls the custom hook gets its own separate state.

Basic habits

  • Use hooks only when React needs them. If the component has to remember a value, run an effect, or keep a ref, then a hook may be useful.
  • Keep hooks at the top. Put hooks near the start of the component so their order stays the same on every render.
  • Do not use hooks just because they exist. If a normal variable can calculate something during render, keep it simple.
  • Use custom hooks for repeated logic. When the same hook logic appears in many components, move it into a useSomething function.

Common mistake

Calling hooks inside conditions

Do not put a hook inside an if.

function LoginForm({ isAdmin }) {
if (isAdmin) {
const [code, setCode] = useState("");
}
return <p>Login</p>;
}

This is wrong because sometimes the hook runs and sometimes it does not. React needs the hook order to stay the same.

What You’ve Learned

  • A hook is a React function whose name starts with use.
  • Hooks give extra abilities to function components.
  • useState stores a value and re-renders the component when that value changes.
  • useEffect runs code after React updates the screen.
  • useRef can hold a DOM reference or a value without re-rendering.
  • Hooks must be called at the top level, in the same order on every render.
  • A custom hook is a useSomething function that reuses hook logic.

Check Your Knowledge

4 questions Show quiz Hide quiz

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What is a React hook?

    Why: A hook is a special React function whose name starts with use, like useState or useEffect. Hooks give function components extra React abilities.

  2. 2

    What does useState mainly do?

    Why: useState stores a value for the component. When we call its setter function, React updates that value and re-renders the component.

  3. 3

    When does useEffect run?

    Why: useEffect runs after React has rendered and updated the screen. It is useful for outside work like changing the document title or calling an API.

  4. 4

    Where should hooks be called?

    Why: Hooks should be called at the top level so React sees them in the same order on every render.

What’s Next?

Now you know what hooks are and why React uses them. Next, we will learn the hook rules properly, because those rules keep React from mixing up state between renders.

React Rules of Hooks