React Forum
Blog & Guide Responses
Feb 14, 2023 · 04:00 AM

You Might Not Need an Effect - discussion (2023-02-14)

Started by Priya Liao
externaleffectsderived stateevent handlersrender postureorchestrationevidencelanes

The "You Might Not Need an Effect" page keeps showing up in code reviews for a reason: so many effects are just derivations or event handlers wearing an effect costume. In the React Tips vocabulary, the alternative is usually: make the contract explicit—derived outputs are derived outputs, orchestration is a named flow, and both leave evidence (logs + UI) so behavior isn't invisible.

Read the article

Which effect patterns did you remove after internalizing this, and what did you replace them with? How do you decide between derive-in-render, stored-derived, and a named orchestration flow effect? Do you log effect/flow behavior as readable contract lines so it's debuggable (especially for async timing)?

Comments (16)

Back to latest
Marisol Vega
Feb 16, 2023 · 04:16 PM

Biggest removal: effects that sync props into state.

We either derive in render or commit into a single source of truth on explicit boundaries. "Sync" effects are usually trying to patch a model problem.

Dmitri Kline
Feb 18, 2023 · 06:06 AM

We started writing contract logs that distinguish derive vs flow explicitly:

txt
[tips] derive=summary reason=inputsChanged keys=3
[tips] flow=nav:normalize reason=query:missingDefaults action=replaceState

That separation prevented the classic mistake: doing orchestration work under the guise of "derivation".

Keira Santos
Mar 01, 2023 · 03:03 AM

Counterpoint: the page can be read as "avoid effects" and teams then do worse things (work in render, random timeouts).

I like a different framing: keep effects, but make them named, bounded, and observable.

Priya Liao
Mar 05, 2023 · 05:05 AM

Yes. The win isn't banning effects; it's banning mystery effects.

If an effect exists, it should have a reason vocabulary and should produce evidence.

Grace McCoy
Mar 18, 2023 · 06:18 PM

We replaced a lot of effects with stored-derived outputs because multiple panels needed the same computed result.

Once derived outputs were centralized, the UI stopped drifting between panels.

Jasper Nguyen
Apr 06, 2023 · 06:06 AM

Long-form: effects become a problem when they hide intent boundaries.

If the user clicked a button, that handler is the boundary. If the route changed, that's the boundary. If you move work into an effect "because it's after render", you lose the ability to explain why work happened.

Nina Kapoor
Apr 18, 2023 · 06:18 PM

Heuristic that worked: if the effect writes state based on state, it's probably derived.

If the effect coordinates the outside world (history, network, focus), it's orchestration and should be named and logged as such.

Camille Duarte
May 10, 2023 · 10:10 AM

Counterpoint: derive-in-render can be expensive and hurt INP.

We moved heavy derives into stored-derived and kept light derives in render, then logged compute/derive separately so perf work was grounded.

Owen Price
Jun 01, 2023 · 06:06 AM

We also made a dev-only effect log buffer and it revealed redundancy.

Once you can see effect spam, you can fix it by moving work to boundaries or by centralizing derive.

Benji Rios
Jul 14, 2023 · 02:14 PM

Long-form counterpoint: teams often replace effects with custom hooks that do the same hidden work.

The fix isn't "no effects"—it's making the work observable and tying it to a contract: lane transitions, intent strings, evidence keys.

Lina Ortega
Aug 19, 2023 · 07:19 PM

Docs tie-in: this page pairs well with patterns and API reference guidance that normalizes named effects + evidence strings.

Related: Patterns Library and API Reference.

Theo Bennett
Sep 18, 2023 · 12:12 PM

We use logs to ensure flows are narratable:

txt
[tips] intent=filter:commit reason=user:enter
[tips] derive=results reason=filter:commit count=27

If you can't narrate it, users can't trust it.

Salma Qureshi
Oct 15, 2023 · 03:15 PM

Long-form: the page is essentially a call to make dependencies and contracts explicit.

Even when you keep an effect, the exercise of justifying it often improves the system because it forces clarity about boundaries.

Evan Brooks
Nov 12, 2023 · 04:04 AM

We also stopped doing navigation in effects unless it was a named normalization flow.

Silent replaceState calls are a great way to make users feel like the app is haunted.

Amina Farouk
Dec 20, 2023 · 06:18 PM

Counterpoint: effects are sometimes the cleanest place to integrate non-React APIs (subscriptions).

But even then, I like having the effect emit a readable artifact (log line, evidence key) so it's part of the system story.

Rowan Pierce
Dec 23, 2023 · 11:23 PM

We treat drafts as multi-truth and commit on boundaries. That removed a lot of effects that existed just to keep drafts and committed truth "in sync".

Once you accept multi-truth, sync effects become unnecessary.

Tomas Rivera
Dec 31, 2023 · 09:09 AM

If you want to apply the page in a codebase: start by writing down your effect inventory and labeling each as derive vs orchestration.

The ones you can't label are the ones that will bite you later.