React Hooks
Table of Contents + −
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:
useStateuseEffectuseRefuseContextuseMemouseCallback
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. usernameholds the current value.setUsernameis the function used to change that value.- When the user types in the input,
onChangeruns. - 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
useEffectruns and checksisLoggedIn. - If
isLoggedInis 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
useSomethingfunction.
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.
useStatestores a value and re-renders the component when that value changes.useEffectruns code after React updates the screen.useRefcan 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
useSomethingfunction that reuses hook logic.
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 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
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
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
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.