1.Introduction
React has become one of the most popular JavaScript libraries for building modern user interfaces. But what truly changed the way developers write React applications was the introduction of Hooks in React 16.8.
Before Hooks, developers mainly relied on class components to manage state, lifecycle methods, and side effects. This often made applications harder to understand and maintain. React Hooks solved this problem by allowing developers to use state and other React features directly inside functional components.
Hooks make React code:
Cleaner
More readable
Easier to reuse
Simpler to maintain
Today, almost every modern React application heavily depends on Hooks for handling state management, API calls, performance optimization, and reusable logic.
From simple hooks like useState and useEffect to advanced hooks like useReducer and useMemo, each hook solves a specific problem and helps developers build better applications more efficiently.
In this blog, we’ll explore the most important React Hooks every developer should know, understand how they work, and learn where they are commonly used in real-world projects.
2.What is useState in React?
useState is one of the most important and commonly used Hooks in React. It allows functional components to store, manage, and update data that can change over time.
In simple terms, useState helps React “remember” values and update the UI whenever those values change.
For example, imagine a counter app:
Count starts at 0
When you click a button, the value increases
The UI updates automatically
Without useState, React would not know when to update the screen.
Why Do We Need useState?
Normally, variables in JavaScript do not persist between renders.
For example:
let count = 0;
function increase() {
count++;
console.log(count);
}
Even though count changes, React will not automatically update the UI because normal variables are not reactive.
This is where useState comes in.
useState tells React:
“This value can change, and whenever it changes, update the UI.”
Syntax of useState
const [state, setState] = useState(initialValue);
Let’s break this down:
const [count, setCount] = useState(0);
Here:
count → Current state value
setCount → Function used to update the state
0 → Initial value of the state
Think of it like this:
count → current value
setCount → updates value
useState(0) → starting value
How useState Works
When state changes, React automatically re-renders the component.
Example:
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>
Increase
</button>
</div>
);
}
How this works:
Initial value starts at 0
User clicks the button
setCount(count + 1) runs
React updates the state
Component re-renders
UI updates automatically
So if count becomes 1, React updates the screen instantly.
Understanding State in Simple Words
You can think of state like a memory box inside a component.
Example:
Counter Component
┌───────────┐
│ count = 0 │
└───────────┘
When the button is clicked:
Counter Component
┌───────────┐
│ count = 1 │
└───────────┘
React notices the change and updates the UI.
Updating State
You update state using the setter function.
Example:
setCount(10);
This changes the value to 10.
You can also update based on the previous value:
setCount(prev => prev + 1);
This is called a functional update.
This approach is useful when the new state depends on the old state.
Example:
setCount(prev => prev + 1);
setCount(prev => prev + 1);
This ensures React updates correctly.
Real-World Use Cases of useState
Counter apps
Form handling
Toggle buttons
Dark/light theme
Search input values
Shopping cart quantity
Modal open/close
3.What is useEffect in React?
useEffect is one of the most powerful Hooks in React. It is used to perform side effects inside functional components.
In simple terms, useEffect allows React components to do something after rendering.
This could include:
Fetching data from an API
Updating the document title
Setting timers
Adding event listeners
Accessing browser APIs
Cleaning up resources
Before Hooks existed, these operations were handled using lifecycle methods in class components like componentDidMount and componentDidUpdate.
But with useEffect, React made this process much simpler and cleaner.
What is a Side Effect?
A side effect is anything that affects something outside the component itself.
Examples:
Calling an API
Changing the webpage title
Starting a timer
Listening to keyboard or mouse events
Updating local storage
These operations happen outside the normal rendering process.
That’s why React provides useEffect.
Syntax of useEffect
useEffect(() => {
// side effect code
}, []);
Let’s break this down:
useEffect(() => {
console.log("Component rendered");
}, []);
Here:
useEffect() → React Hook
First argument → Function containing side effect code
Second argument → Dependency array
How useEffect Works
React first renders the component.
After rendering is completed, React runs the code inside useEffect.
Think of it like this:
1. Component renders
2. UI appears on screen
3. useEffect runs
This is why useEffect is called a side-effect Hook.
Example: Updating the Document Title
import { useState, useEffect } from "react";
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Count: ${count}`;
});
return (
<button onClick={() => setCount(count + 1)}>
{count}
</button>
);
}
What happens here?
Component renders
useEffect runs
Browser tab title updates
Every time count changes, effect runs again
Understanding the Dependency Array
The dependency array controls when the effect should run.
This is one of the most important concepts in useEffect.
1. No Dependency Array
useEffect(() => {
console.log("Runs after every render");
});
Effect runs:
After first render
After every re-render
2. Empty Dependency Array
useEffect(() => {
console.log("Runs only once");
}, []);
Effect runs:
- Only once after initial render
This behaves similar to:
componentDidMount()
Common use cases:
API calls
Initial setup
Fetching data
3. Dependency Array with Values
useEffect(() => {
console.log("Runs when count changes");
}, [count]);
Effect runs:
Initial render
Whenever count changes
React watches the dependency value.
If the value changes, React reruns the effect.
Fetching Data with useEffect
One of the most common use cases.
Example:
import { useEffect, useState } from "react";
function Users() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then(res => res.json())
.then(data => setUsers(data));
}, []);
return (
<div>
{users.map(user => (
<p key={user.id}>{user.name}</p>
))}
</div>
);
}
What happens here?
Component loads
useEffect runs once
API request happens
State updates
UI re-renders with data
Cleanup Function in useEffect
Sometimes effects create resources that need cleanup.
Examples:
Timers
Event listeners
Subscriptions
React provides a cleanup function for this.
Syntax:
useEffect(() => {
// setup code
return () => {
// cleanup code
};
}, []);
Real-World Use Cases of useEffect
You’ll use useEffect for:
API calls
Authentication checks
Timers and intervals
Event listeners
Local storage
Updating document title
Real-time data fetching
Socket connections
4.Final Takeaway
React Hooks completely changed the way developers build React applications. Among all Hooks, useState and useEffect are the foundation of modern React development.
useState helps components store and manage dynamic data, while useEffect allows components to interact with the outside world through side effects like API calls, timers, and event listeners.
Together, these two Hooks make React applications:
More dynamic
More interactive
Easier to maintain
Cleaner to write
Top comments (0)