Drills Repository
41 Drills · All Belts · useeffect
Dependency arrays describe used values
A dependency array declares which reactive values from render scope a Hook actually uses, allowing React to determine when synchronization or recalculation is genuinely needed. It functions as a correctness contract rather than a manual performance switch or render limiter.
Empty dependency arrays
An empty dependency array tells React the Effect uses no reactive values, so it synchronizes only when the component mounts and unmounts. In development, Strict Mode may still run it through one extra setup-and-cleanup cycle to verify correctness.
Empty dependency array vs no dependency array
An empty dependency array tells React the Effect depends on no reactive values, so it runs only once after the initial commit. Omitting the dependency array entirely instead tells React to run the Effect after every single commit.
Effects run after rendering
Rendering in React should stay pure and only calculate JSX. DOM manipulation like play() is a side effect, so it belongs in useEffect, which runs after React commits the DOM updates.
Calculating derived data during render
fullName is fully derived from existing state (firstName and lastName), so storing it separately creates redundant state and extra renders. Calculating it directly during render is simpler and avoids unnecessary updates.
Effect lifecycle vs component lifecycle
Components go through mounting, updating, and unmounting phases. Effects instead describe synchronization processes that can repeatedly start and stop whenever dependencies change.
Missing dependency causes stale Effect
Effects capture values from the render in which they were created through closures, not through live references. With an empty dependency array, the Effect runs only once, so it keeps using the initial roomId value even after roomId changes on later renders.
Object dependency recreated every render
React compares Effect dependencies using Object.is, which checks reference identity rather than deep equality. An object literal created during render receives a new reference on every render, so the dependency appears changed even when its contents are identical.
Function dependency recreated every render
A function declared inside the render body is a new function object on every render, regardless of whether its logic stays identical. Because React compares dependencies by reference identity using Object.is, this new reference causes the Effect to re-run on every render.
Running an effect only once
React expects an Effect to declare every reactive value it reads in its dependency array, so userId must remain listed rather than being suppressed. If the analytics call genuinely needs to fire only once, a ref-based guard can control repeated execution while still keeping dependency tracking accurate.
Functional updater removes dependency need
An updater function receives the latest pending state directly from React at update time, so the interval callback no longer needs to read count from its closure. This removes count as a reactive dependency, preventing the interval from being torn down and recreated on every tick.
Missing dependency stale closure
Effects close over the values present in the render where they were defined, capturing a fixed snapshot rather than a live reference. Because count is omitted from the dependency array, the Effect never re-runs with newer values, so it keeps logging the stale, closed-over count.