Drills Repository
41 Drills · All Belts · useeffect
What Is a Dependency Array For?
A dependency array declares which reactive values from render scope a Hook actually reads, letting React determine when synchronization or recalculation is genuinely needed. In both useEffect and useMemo, listing every value the callback reads is what tells React when a rerun or recalculation must happen, nothing about how often the component itself renders.
Calling DOM Methods Inside useEffect
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.
Storing fullName in State via useEffect
A value that can be computed from existing props or state doesn't need its own state variable, since storing it separately creates redundant state and forces an extra render just to keep it in sync. Here, fullName is fully derived from firstName and lastName, so it can be calculated directly during render instead of synchronized through a separate useEffect.
Effect lifecycle vs component lifecycle
A component's lifecycle describes discrete phases it passes through once each mount: mounting, updating, and unmounting. An Effect's lifecycle is different: it describes a synchronization that can start and stop repeatedly, independent of how many times the component itself re-renders.
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.
Empty dependency arrays
An empty dependency array tells React that an Effect uses no reactive values, so it only needs to synchronize once when the component mounts and once when it unmounts. Here that means connect() runs once on mount and disconnect() runs once on unmount, though Strict Mode may still run that pair an extra time in development to check the cleanup.
Returning null and effects
Returning null only changes the rendered output; it does not prevent the component from rendering or hooks from executing. React still calls the component function and processes its effects as part of the render lifecycle.
AbortController Custom Hook - Attaching Cancellation to Every Fetch
Calling abort() on an AbortController permanently marks its signal as aborted, so a controller cannot be reused to guard a subsequent request once it has already cancelled one. Creating the controller fresh inside the effect ties its lifecycle to that specific run, ensuring cleanup only cancels the request that run itself initiated rather than a future one.
Asserting Immediately After fireEvent without waitFor
React's state update scheduler runs independently of the promise chain a test happens to await, so awaiting an event dispatch does not by itself guarantee React has flushed the resulting re-render to the DOM. act() and waitFor() explicitly instruct the test environment to process React's pending update queue and commit DOM changes before assertions run, closing that timing gap.
Passing an async Function Directly to useEffect
An async function always returns a Promise no matter what its body returns, so useEffect gets that Promise instead of the cleanup function, and ignores it since it isn't a function or undefined. The fix defines a separate async inner function, calls it from a synchronous effect callback, and returns the controller.abort cleanup directly from that outer callback.
How to Run useEffect Conditionally
React requires Hooks to be called unconditionally in the same order on every render, so a Hook call itself cannot sit inside a branch. Declaring useEffect normally and placing the condition inside its callback keeps the Hook order stable while still letting the synchronization logic run only when needed.
Object Literal in a useEffect Dependency Array
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.