When people start learning React, two terms appear everywhere: useState and useEffect. At first, they might feel confusing because they look different from normal JavaScript functions. But once you understand what problem they solve, they become much easier.
This blog explains them in a simple way.
What is useState?
Imagine you have a counter application.
When someone clicks a button, the number should increase.
The question is:
How does React remember the updated value?
This is where useState comes in.
useState allows React components to store and update data.
Without State
function Counter() {
let count = 0;
function increase() {
count++;
console.log(count);
}
return (
<>
<h1>{count}</h1>
<button onClick={increase}>
Increase
</button>
</>
)
}
You may expect this to work.
But it doesn't.
Why?
Because React re-renders components, and when it does, count becomes 0 again.
Using useState
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<>
<h1>{count}</h1>
<button
onClick={() => setCount(count + 1)}
>
Increase
</button>
</>
)
}
Now it works.
Why?
const [count, setCount] = useState(0);
This line creates two things:
count → stores the value
setCount → updates the value
0 is the initial value.
Whenever setCount() runs:
- State updates
- Component re-renders
- Updated value appears on screen
Why Do We Need State?
State is useful whenever data changes.
Examples:
- Counter applications
- Form inputs
- Dark mode toggle
- Shopping cart items
- API data
If data changes and UI should update:
You probably need state.
What is useEffect?
Now imagine something should happen after the component renders.
Examples:
- Calling an API
- Updating document title
- Running timers
- Listening to events
React provides useEffect for this.
Think of it like:
"Run this code after rendering."
Basic Example
import { useEffect } from "react";
function App(){
useEffect(() => {
console.log("Component rendered");
});
return <h1>Hello</h1>
}
- This runs after every render.
- Running Effect Only Once
- Sometimes you only want code to run once.
Example:
`useEffect(()=>{
console.log("Run only once");
},[])
`
The empty array means:
Render component
|
Run effect once
|
Never run again
Usually used for:
- API calls
- Initial setup
- Fetching data
- Running Effect When Value Changes
`useEffect(()=>{
console.log("Count changed");
},[count])`
Now effect runs only when count changes.
Example:
function Counter(){
const [count,setCount]=useState(0);
useEffect(()=>{
console.log("Count Updated");
},[count])
return(
<>
<h1>{count}</h1>
<button
onClick={()=>setCount(count+1)}
>
Increase
</button>
</>
)
}
Whenever button clicks:
count changes
|
component re-renders
|
effect runs
Cleanup Function
Some things must be cleaned when component disappears.
Example:
useEffect(()=>{
const timer=setInterval(()=>{
console.log("running");
},1000);
return ()=>{
clearInterval(timer);
}
},[])
Why cleanup?
Without cleanup:
Timers continue running
Event listeners remain
Memory leaks happen
Cleanup prevents this.
A Simple Way to Remember
useState
"I want React to remember something."
useEffect
"I want React to do something after rendering."
Final Thoughts
Most beginner React applications are built using these two hooks.
If you understand:
- How state updates UI
- When components re-render
- When effects execute
React becomes much easier.
You do not learn React by memorizing hooks.
You learn React by understanding:
"When data changes, what should happen?"
That is where useState and useEffect become useful.
Top comments (0)