Sweat beading on my forehead in a silent San Francisco co-working space, I deleted 200 lines of Redux boilerplate for a simple API call—and felt the app breathe again.
What I stopped doing in React projects changed everything. Not adding more hooks or patterns. No. Subtracting. Ruthlessly.
The original revelation? “Writing maintainable React code isn’t about following best practices. It’s about knowing which practices to stop following.”
Writing maintainable React code isn’t about following best practices. It’s about knowing which practices to stop following.
That’s the hook. And damn, it landed.
Why Redux for Server State Was Killing Me
Picture this: every API fetch birthed a monster. Three action types. An async thunk. Reducer cases. Selectors. useDispatch, useSelector hell in components. 200+ lines to list campaigns.
Here’s the before, straight from the trenches:
// 3 action types, 1 action creator, 1 reducer, 2 selectors...
const FETCH_CAMPAIGNS_REQUEST = "FETCH_CAMPAIGNS_REQUEST";
// ... (you get it)
Wiring it up? A useEffect dispatching on page change. Loading states scattered. Errors buried.
Then, SWR. Fifteen lines. A hook. Mutate on updates. Suspense-ready. Caching? Automatic. Stale-while-revalidate? Baked in.
const { data: campaigns, error, isLoading } = useSWR('/campaigns?page=' + page);
Improvement? Fetch logic vanished from components. Bundle size dropped 15%. Debugging? Non-issue—SWR’s devtools show it all.
But here’s my unique spin: Redux for server state echoes jQuery’s grip on early web dev. Everyone nailed every problem with it, until fetch() and libraries said, ‘Nah.’ React’s next shift? Server Components will nuke most client-side state machines entirely.
Is Chaining useEffects Still Worth It?
useEffect chains. Five of ‘em per component. One for fetch. One for optimistic updates. One for subscriptions. Cleanup? Nightmares.
Stopped cold. Swapped for a single reducer pattern with useReducer + a library like Zustand (tiny, no provider boilerplate). Or better: TanStack Query for queries/mutations.
Why? Effects don’t compose. They fight—stale closures, infinite loops if deps misfire. Reducer centralizes. One truth source.
In my platform? Conversations module went from 8 effects to 2 Query hooks. Re-renders halved. Race conditions? Gone.
Look, React docs push effects as ‘side effects king,’ but that’s 2018 thinking. Architecture’s flipping to queries as first-class.
Short para. Brutal truth.
Prop Drilling: Dead on Arrival
Passing props eight levels deep. UserId from App to Footer tooltip. Every refactor? Prop cascade refactor.
Killed it. Context? Yes, but sparse—org-wide stuff only. Components? Consume via hooks from a lightweight store.
Jotai or Valtio. Atom-based. No context providers everywhere. Subscribe surgically.
const userId = useAtom(userAtom);
Multi-org permissions? One atom per org. Scales. No ‘Context hell’.
Custom Hooks for Mundane Stuff
useFetchUser. usePaginateList. useOptimisticUpdate. Reinventing wheels.
Halted. Libraries own this: React Query/SWR for data. Framer Motion for animations. Headless UI for… heads.
My codebase? Hook count from 45 to 12. All battle-tested. Bugs? Near zero.
Corporate hype alert: Facebook’s ‘hooks fix composition’ pitch ignores library ecosystems exploding for good reason.
Inline Styles and Emotion Overload
CSS-in-JS bloat. Emotion caches. Bundle swell.
Switched to Tailwind + vanilla CSS modules. Utility classes. Zero runtime.
App load time? 40% faster on mobile. Tree-shakeable. Theming? CSS vars.
Why Does This Matter for React Devs in 2024?
React’s maturing past ‘kitchen sink’ phase. Hooks enabled power, but bred over-engineering. Stopping these? It’s pruning for growth.
Metrics from my project: Lines of code down 65%. Onboarding new devs? Days, not weeks. Bugs fixed 3x faster.
Prediction: By 2025, React Server Components make client state a vestige. Tools like SWR evolve into full-stack fetchers. Redux? Legacy for rare global sync.
Skeptical? Test it. Fork a repo, SWR-ify one slice. Feel the lift.
And.
That’s the purge.
🧬 Related Insights
- Read more: 216 Pages of GeoCities Nostalgia, One Python Script, and a Lot of Keyboard Rage
- Read more: Tiny Linux Giants: The Base Images Shrinking Your Container Empire
Frequently Asked Questions
Should I ditch Redux entirely in my React app?
For server state, yes—swap to React Query or SWR. Keep Redux only for complex client-side logic like undo/redo.
What’s better than useEffect chains in React?
useReducer or Zustand for local state, TanStack Query for data fetching. Fewer effects, saner deps.
Is SWR production-ready for React projects?
Absolutely—Vercel backs it, handles caching, mutations, pagination out-of-box. Scales to enterprise.