Skip to main content
useEffect is a React Hook that lets you synchronize a component with an external system.

Parameters

() => (() => void) | void
required
The function with your Effect’s logic. Your effect function can optionally return a cleanup function.
  • React will call your effect function after the component is added to the screen (after render)
  • React will call your cleanup function (if provided) before the component is removed from the screen
  • If dependencies change, React will first call the cleanup function with old values, then call the effect function with new values
Your effect function should be pure and should not take any arguments.
Array<mixed> | void | null
The list of all reactive values referenced inside the effect code.
  • If omitted, the effect runs after every render
  • If [] (empty array), the effect runs only once (on mount)
  • If [dep1, dep2], the effect runs when any dependency changes
React will compare each dependency with its previous value using Object.is.

Returns

useEffect returns undefined.

Usage

Connecting to an external system

Some components need to stay connected to external systems while they’re displayed:

Fetching data

In React 18+, consider using Suspense for data fetching, or use a data fetching library like React Query, SWR, or Redux Toolkit Query instead of manually managing loading states.

Subscribing to events

Running once on mount

Pass an empty dependency array to run the effect only once:
In development with Strict Mode, React will run effects twice to help you find bugs. This is intentional and only happens in development.

Effect dependencies

Cleanup function

The cleanup function runs:
  1. Before the effect runs again (if dependencies changed)
  2. When the component unmounts

Common Use Cases

Updating document title

Working with intervals

Local storage sync

Triggering animations

TypeScript

Troubleshooting

My effect runs twice on mount

In development with Strict Mode, React intentionally runs effects twice to help find bugs:
This is intentional and only happens in development. Make sure your cleanup function properly cleans up what your effect does.

My effect runs on every render

This happens when you forget the dependency array or include values that change on every render:

My effect depends on a function

Functions created in the component body are new on every render:

Infinite loop

If your effect updates state that it also depends on:

Effect uses stale state

If you omit dependencies, the effect will use stale values:

When NOT to use useEffect

Transforming data for rendering

Handling user events

Initializing state