Overview
TheuseEffect hook lets you perform side effects in functional components. Side effects include data fetching, subscriptions, timers, manual DOM manipulation, and more.
Effects run after the component renders, keeping your side effect logic separate from the rendering logic.
Signature
Parameters
A function containing the side effect code. This function runs after the component renders to the DOM.The effect function can optionally return a cleanup function. The cleanup function runs:
- Before the effect runs again (if dependencies changed)
- When the component unmounts
An optional array of dependencies. The effect will only re-run if one of these values has changed since the last render.
- Omit the array: Effect runs after every render
- Empty array
[]: Effect runs only once after the initial render - Array with values: Effect runs when any value in the array changes
Usage
Running Effects on Every Render
If you omit the dependency array, the effect runs after every render:Running Effects Once (Component Mount)
Pass an empty array[] to run the effect only once after the initial render:
Running Effects When Dependencies Change
Provide an array of dependencies to control when the effect runs:Cleanup Functions
Return a cleanup function from your effect to clean up resources:Multiple Effects
You can use multipleuseEffect calls in a single component to separate concerns:
Practical Examples
Document Title Updates
Event Listeners
Focus Management
How It Works
TheuseEffect hook is implemented in packages/runtime/src/hooks.js:163-271. Here’s the execution flow:
-
First Render: On the initial render, the effect is scheduled to run after rendering completes using
setTimeout(..., 0). -
Subsequent Renders: On re-renders, GlyphUI compares the new dependencies with the previous dependencies:
- If dependencies haven’t changed, the effect is skipped
- If dependencies changed, the cleanup function (if any) runs first, then the new effect runs
-
Cleanup Execution: Cleanup functions are stored per-hook-index in
componentHooksStoreand run:- Before the effect re-runs (when dependencies change)
- When the component unmounts (via
runCleanupFunctions())
- Async Execution: Effects run asynchronously after the render commits to the DOM, so they don’t block rendering.
Dependency Array Rules
Include All Dependencies
Every value from the component scope that’s used inside the effect should be included in the dependency array:Avoid Object Dependencies
Be careful with object and array dependencies. GlyphUI uses strict equality (!==) to compare dependencies, so objects are compared by reference:
Empty Array for Mount-Only Effects
Use[] when the effect should run only once:
Common Pitfalls
Stale Closures
Be aware of stale closures when using effects:Infinite Loops
Avoid creating infinite loops by updating state that’s in the dependency array:Related Hooks
- useState - Often used together with useEffect
- useRef - Store mutable values that don’t trigger effects
- useCallback - Memoize callbacks used in effect dependencies