When to use useEffect:
- External systems only: DOM, timers, WebSocket, postMessage
- State sync with non-React systems
When NOT to use useEffect:
- β Derived state from props (compute inline or use
useMemo)
- β Data fetching (use GraphQL
useQuery instead)
- β Syncing local state with props (use controlled components)
Custom hooks:
- Extract all business logic from components
- π¨ ALL HOOKS MUST BE UNIT TESTED π¨
- Keep components display-only
Only use useEffect for external systems outside our frontend codebase:
When NOT to Use useEffect
Critical rule: Only include dependencies if you want the effect to re-run when they change.
Use useRef for values that shouldn't trigger re-runs but need to stay current:
Always return cleanup functions for subscriptions, timers, and event listeners:
Always extract React logic into custom hooks. Keep components display-only.
π¨ ALL HOOKS MUST BE UNIT TESTED π¨
See Unit Testing for comprehensive hook testing patterns with React Testing Library.
For more detailed technical guidance, see these reference files: