After maintaining several production React apps over the past few years, here are patterns I actively stopped using and what I do instead:
1. Stopped using useEffect for derived state
Old habit:
const [items, setItems] = useState([]) const [filteredItems, setFilteredItems] = useState([]) useEffect(() => { setFilteredItems(items.filter(i => i.active)) }, [items])
Now I just compute it during render:
const filteredItems = useMemo(() => items.filter(i => i.active), [items])
Or honestly, skip the useMemo entirely if the list is small. An extra filter on 50 items is free.
2. Stopped putting everything in global state
Not every piece of data needs to be in Redux/Zustand. Modal open/closed? Local state. Form values? Local state. The selected tab? Local state. Global state should be for data that multiple unrelated components need simultaneously.
3. Stopped creating wrapper components for everything
I used to create <Card>, <Container>, <Wrapper> components that just added a className. Now I just use the className directly. Fewer files, fewer indirection layers, easier to find what applies what styles.
4. Stopped using index as key in lists
This one bit me in production. A list of editable inputs keyed by index β reorder the list and suddenly inputs have the wrong values. Always key by a stable identifier.
5. Stopped splitting components too early
A 200-line component that's only used once and handles one cohesive piece of UI is fine. Splitting it into 6 tiny components that each need props drilled through them just to satisfy some arbitrary line count rule makes it harder to follow.
What patterns have you actively removed from your React code?