useEffect(setup, dependencies) takes a setup function and an optional dependency array. React 7,897 calls the setup function after the commit that follows a render, never during the render itself. Mutations, network requests, subscriptions, timers and logging all belong there, because none of them may happen while your component is computing its JSX.
import { useState, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}); // no array: runs after every render
return <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>;
}document.title is not part of the React tree, so React cannot set it for you; the effect keeps it in step with count. That is the test to apply before reaching for useEffect: is there something outside React that has to be told about this state? If the answer is no — if you are only deriving a value, reacting to a click, or resetting state — an effect is the wrong tool, and Effects You Do Not Need lists the alternatives.