DEV Community

PixelPerfect Pro
PixelPerfect Pro

Posted on

🚫 9 Things You Shouldn’t Do in React (The 9 Deadly Sins 😱)

Welcome, fellow React developers.

You thought React was easy until you opened a file and saw:

useEffect(() => {
  setState(state + 1);
}, [state]);
Enter fullscreen mode Exit fullscreen mode

You realize it's re-rendering forever. Your browser crashes. Your laptop fans scream. You scream.

This article is a tour of the 9 deadly sins of React — complete with real pain, bad decisions, and some trauma bonding.


1. 🧟‍♂️ Thou Shalt Not Use Class Components (Unless You're Archaeologist)

Back in 2017, class components were React’s hot new thing.
Today, they’re the rotary phones of development.

I once joined a project where the main component looked like this:

class Dashboard extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      user: {},
      metrics: [],
      loading: true,
    };
  }

  async componentDidMount() {
    const data = await fetchDashboardData();
    this.setState({ ...data, loading: false });
  }

  shouldComponentUpdate(nextProps, nextState) {
    return JSON.stringify(this.state) !== JSON.stringify(nextState);
  }

  // and 1000 more lines...
}
Enter fullscreen mode Exit fullscreen mode

By the time I finished reading it, my eyes needed pagination.

☠️ Why it hurts:

  • this binding is a nightmare
  • Logic reuse? Good luck!
  • Too many lifecycle methods

✅ Use function components + hooks


2. 💥 The “12 useStates in One File” Crime Scene

Here’s something I actually saw in production:

const [step, setStep] = useState(0);
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
const [formTouched, setFormTouched] = useState(false);
const [isSubmitted, setIsSubmitted] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [serverError, setServerError] = useState(null);
const [redirect, setRedirect] = useState(false);
Enter fullscreen mode Exit fullscreen mode

This component had:

  • Business logic
  • UI logic
  • Form validation
  • API handling
  • Toasts
  • Animations

...all jammed into one monstrous 500-line file.

☠️ Why it hurts:

  • Impossible to read or debug
  • No separation of concerns

✅ Use useReducer or custom hooks like useLoginForm()


3. 🤯 Using useEffect for Everything Because It “Just Works”

useEffect(() => {
  const data = expensiveCompute(props.items);
  setState(data);
}, [props.items]);
Enter fullscreen mode Exit fullscreen mode

Why not use useMemo, you ask?
Because this dev believed useEffect is React’s if-else for life.

☠️ Why it hurts:

  • Side effects happen on re-render → trigger state updates → re-render again

✅ Use useMemo for computed values and useEffect for async stuff


4. 🔁 Hook Dependency Hell (a.k.a. “The Loop of Doom”)

const [count, setCount] = useState(0);

useEffect(() => {
  setCount(prev => prev + 1);
}, [count]); // INFINITE LOOP TIME 🚨
Enter fullscreen mode Exit fullscreen mode

Bonus points if the dev added a console log and then:

console.log("count:", count); // console never stops
Enter fullscreen mode Exit fullscreen mode

☠️ Why it hurts:

  • You crash the tab
  • You question your career choices

✅ Use guards or useRef to break circular updates


5. 🌍 Using Global State Like It’s 1995

Every UI interaction hits context. Close a dropdown? Whole page re-renders.

const { isModalOpen, setIsModalOpen } = useContext(GlobalContext);
Enter fullscreen mode Exit fullscreen mode

☠️ Why it hurts:

  • Global context = global performance hit
  • Trivial things become untestable

✅ Keep state local unless it truly must be shared


6. ⚶️ Redux Isn’t Dead — But You’re Using It Wrong

Still doing this?

dispatch({ type: 'SET_AUTH', payload: true });
Enter fullscreen mode Exit fullscreen mode

And you have:

  • /actions/user.js
  • /reducers/userReducer.js
  • /types/userActionTypes.js

That’s classic Redux. It's like writing essays for text messages.

☠️ Why it hurts:

  • Boilerplate ☑
  • Fragile action chains ☑
  • Slow onboarding ☑

✅ Use:

  • Redux Toolkit (RTK)
  • RTK Query for async state
  • Zustand, Jotai, React Query as simpler alternatives
const authSlice = createSlice({
  name: 'auth',
  initialState: { loggedIn: false },
  reducers: {
    login: (state) => { state.loggedIn = true },
    logout: (state) => { state.loggedIn = false },
  },
});
Enter fullscreen mode Exit fullscreen mode

💡 Redux isn’t dead. But your 2017 version of Redux should be.


7. 🏠 Real Project Structure, Not Folder Soup

Bad:

src/
  App.jsx
  helpers.js
  FinalFix.jsx
  testComp3.jsx
  utils2.js
Enter fullscreen mode Exit fullscreen mode

Opening that repo feels like entering a garage with no shelves.

☠️ Why it hurts:

  • You can't find anything
  • No domain boundaries

✅ Do this instead:

/src
  /shared
    /ui       # Reusable UI (buttons, inputs)
    /hooks    # Custom hooks
    /lib      # Utilities
    /types    # Global types/interfaces
  /features
    /auth
      /components
      /hooks
      /auth.slice.ts
    /dashboard
      /components
      /hooks
  /pages
    /dashboard
    /login
  /entities
    /user
    /product
Enter fullscreen mode Exit fullscreen mode

Think "group by feature", not by file type.


8. 🔤 Naming Components Like a Drunken Goblin

Real names I’ve seen:

  • ThingWrapper.jsx
  • HandlerStuff.js
  • FinalFinalForm2.jsx
  • useMagicState.js
  • YoloModal.jsx
  • NoIdea.jsx

☠️ Why it hurts:

  • Impossible to understand
  • Refactoring becomes a horror movie

✅ Use clear, purpose-driven names:

  • Components: UserCard, ProductList, LoginForm
  • Hooks: useUser, useFormValidation
  • Utils: getDateRange, debounce

😂 If your filename has "Final" and a number in it, stop. Reboot your brain.


9. 🧼 God Components That Do Everything

One file:

  • Fetches data
  • Handles auth
  • Renders modals
  • Shows toasts
  • Writes to Firestore
  • Animates a wizard hat spinning

☠️ Why it hurts:

  • Not testable
  • Not reusable
  • Not readable

✅ Break it down:

  • useUserData
  • UserForm
  • ToastManager
  • UserModal

Split UI, logic, and data.


⚠️ Bonus: Don’t Be Stubborn — Be Smart

React evolves. So should you.

✅ Read the docs
✅ Learn new APIs
✅ Avoid outdated patterns

Your future self will thank you.


🧠 Wrap-Up: React Is Simple — Until It Isn’t

React's flexibility is a gift and a curse.

🔁 TL;DR

  1. No more class components
  2. Don’t abuse useState
  3. useEffect isn't your calculator
  4. Respect hook deps
  5. Global state ≠ default
  6. Use Redux Toolkit or better
  7. Structure your app
  8. Name things clearly
  9. Break up god components

What React sins have you seen? Share your horror stories and memes 👇

Top comments (0)