useState and useEffect are two of the most important React hooks. useState helps components store changing values, while useEffect helps components run side effects such as data fetching, timers, subscriptions, or DOM-related work after rendering.
useState adds state to function components. It returns the current value and a setter function used to update that value.
const [count, setCount] = useState(0)useEffect runs code after React renders the component. It is commonly used for data fetching, timers, subscriptions, and syncing React with the outside world.
| Pattern | When it runs |
|---|---|
useEffect(() => { ... }) | After every render |
useEffect(() => { ... }, []) | Only after the first render |
useEffect(() => { ... }, [value]) | When the listed dependency changes |
import { useEffect, useState } from 'react'
function Timer() {
const [seconds, setSeconds] = useState(0)
useEffect(() => {
const id = setInterval(() => {
setSeconds(current => current + 1)
}, 1000)
return () => clearInterval(id)
}, [])
return <p>Seconds: {seconds}</p>
}import { useEffect, useState } from 'react'
function Users() {
const [users, setUsers] = useState([])
const [loading, setLoading] = useState(true)
useEffect(() => {
fetch('/api/users')
.then(response => response.json())
.then(data => {
setUsers(data)
setLoading(false)
})
}, [])
if (loading) return <p>Loading...</p>
return (
<ul>
{users.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
)
}Some effects create resources that must be cleaned up, such as intervals, subscriptions, or event listeners. Returning a function from useEffect lets React clean them up when the component unmounts or before the effect runs again.
| Mistake | Why it causes bugs | Better approach |
|---|---|---|
| Forgetting dependencies | Effect may use stale values | Include the values the effect depends on |
| Putting non-side-effect logic in useEffect | Adds unnecessary complexity | Keep normal calculations in render when possible |
| Forgetting cleanup | Can create memory leaks or duplicate listeners | Return a cleanup function when needed |
| Using one large effect for unrelated tasks | Makes code harder to understand | Split unrelated effects into separate hooks |
useState for local changing valuesuseEffect only for real side effectsuseState and useEffect are core tools in modern React. useState lets components store changing values, while useEffect lets components perform side effects after rendering. Learning when to use each one, and when not to, is a major step toward writing cleaner React applications.
Explore 500+ free tutorials across 20+ languages and frameworks.