React Forum
Blog & Guide Responses
Nov 12, 2022 · 04:00 AM

You Might Not Need an Effect - discussion (2022-11-12)

Started by Mina Calder
externalreact.deveffectsderived statecontractsdebugging

The “you might not need an effect” argument resonates, but in real apps the hard part is: what do you replace the effect with so the behavior is still explainable and reproducible?

Read the article

When you delete effects, do you typically replace them with derived evidence stored in the route doc, or with explicit event handlers? What are your heuristics for spotting “sync effects” that should be contracts instead? Do you render any evidence markers so it’s clear *why* state looks the way it does after a refactor?

Comments (10)

Back to latest
Maya Henson
Nov 12, 2022 · 04:06 AM

If an effect exists to settle state, it’s probably hiding a missing contract decision.

Dmitri Kline
Nov 12, 2022 · 04:14 AM

Our most common replacement is “store derived evidence once”.

If multiple panels need the same derived thing, you don’t want them all re-deriving and disagreeing after render.

Related: Core Concepts Best Practices and State Management Best Practices.

Salma Qureshi
Nov 12, 2022 · 04:22 AM

A common “delete the effect” refactor for us is moving logic into an explicit handler + writing evidence:

tsx
const doc = useRouteDoc('search');
function onQuery(next: string) {
  doc.write('query', next);
  doc.write('queryEvidence', { at: Date.now(), reason: 'input' });
}
return <input onInput={(e) => onQuery(e.currentTarget.value)} />;
Keira Santos
Nov 12, 2022 · 04:31 AM

Counterpoint: sometimes effects are the least bad tool for integrating with external APIs.

But I agree with the article that “sync internal state after render” is usually just a smell.

Mina Calder
Nov 12, 2022 · 04:36 AM

Yes. I’m mostly talking about the internal ones: “when A changes, set B” effects.

When we replace them with derived evidence, flicker goes away and tests become less racy.

Keira Santos
Nov 12, 2022 · 04:39 AM

Exactly. External sync: ok. Internal sync: contract it.

Camille Duarte
Nov 12, 2022 · 04:47 AM

We deleted a bunch of effects and the unexpected result was: fewer “back button” bugs.

Turns out many of our effects were quietly rewriting state after navigation.

Rowan Pierce
Nov 12, 2022 · 04:56 AM

Heuristic I use: if an effect exists to keep two internal variables in sync, it’s wrong.

Either one is derived from the other, or you need a real event boundary where the change is decided.

Amina Farouk
Nov 12, 2022 · 05:07 AM

Evidence marker helped us avoid regressions during effect deletions:

tsx
return <div data-evidence={JSON.stringify(doc.read('queryEvidence'))} />;

If the marker disappears or changes shape, tests catch it immediately.

Theo Bennett
Nov 12, 2022 · 05:21 AM

This is also related to performance: “settle state after render” effects cause extra rerenders and often make typing feel worse.

Deleting them can be a perf win without touching micro-optimizations.

Inez Park
Nov 12, 2022 · 05:32 AM

If you delete an effect and the UI becomes simpler to explain, you probably did the right thing.

Benji Rios
Nov 12, 2022 · 05:44 AM

The article is right, but the “replacement” is the hard part.

If you can’t explain the new contract from a screenshot, you’ll just re-add the effect later under pressure.