Side Effect

Anything a component does besides return UI: fetching, timers, subscriptions, touching the DOM. Work with consequences outside render.

the fetching and timer stuffthings that happen outside drawing the pageuseEffect stuffside affectcode that reaches outside the componentsubscriptions and timersdo something after it renderstalking to the outside world

See it

Live demo coming soon

What it is

Rendering is supposed to be pure: same props and state in, same UI out, nothing else touched. A side effect is everything that breaks that purity on purpose: calling an API, starting an interval, adding an event listener, writing to localStorage, firing an analytics event, focusing an input. Frameworks give effects their own slot (React's useEffect, Vue's watchEffect and onMounted, Svelte's $effect) so the work is scheduled outside render instead of happening during it. Exact timing differs per API and per trigger: React's useEffect fires after the browser paints while useLayoutEffect fires after the DOM commit but before paint, and Vue and Svelte each ship their own pre-DOM and post-DOM variants. Choose by whether the user should ever see a frame before your effect runs.

Use an effect only to synchronize with something outside your framework. If the value can be computed from existing state during render, just compute it: derived data needs no effect. If it happens because a user clicked something, it belongs in the event handler. Most 'why does this run twice' bugs are effects doing a handler's job.

The gotcha is cleanup. Every subscription, timer, and in-flight request needs a teardown function or you collect duplicate listeners, leaked memory, and responses arriving from a screen the user left two navigations ago. React's Strict Mode mounts twice in development on purpose, specifically to make missing cleanup fail loudly.

Ask AI for it

Inspect this component and name the external system it actually needs to synchronize with: a socket, an interval, a window or media event, an observer, localStorage, a third-party widget, an analytics call. Implement one focused useEffect for that system. Setup goes in the body, every reactive value the effect reads goes in the dependency array, and the returned cleanup tears down exactly what the setup created, so it stays correct when dependencies change and under React Strict Mode double-mounting. If the effect performs a fetch, create an AbortController, pass its signal to the request, and abort it in the cleanup. Anything derivable from props and state during render, or triggered by a user action, does not belong in an effect: move it to a computed value or an event handler and tell me what you moved and why.

You might have meant

component lifecycledata fetchinghook composablestate managementref

Go deeper