What does the dependency array of useEffect actually control?
It tells React which values the effect reads, so the effect re-runs only when one of them changes. An empty array means run once after mount; omitting the array entirely means run after every render, which is how infinite loops start. Leaving a used value out is the other failure — the effect closes over a stale value and keeps using it forever.