React Class to Hooks Migration Guide

React Hooks (introduced in 16.8) are now the standard. Class components with `this.setState` and lifecycle methods are legacy. This guide provides direct translation patterns for migrating typical class components to functional components with Hooks.

State Management: useState

// Class
class Counter extends React.Component {
  state = { count: 0, text: '' };
  render() {
    return <div>{this.state.count}</div>;
  }
}

// Hooks
function Counter() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState(''); // Split state for better granularity
  return <div>{count}</div>;
}

Lifecycle: useEffect

`useEffect` replaces `componentDidMount`, `componentDidUpdate`, and `componentWillUnmount`.

// Class
componentDidMount() {
  API.subscribe(this.props.id);
}
componentDidUpdate(prevProps) {
  if (prevProps.id !== this.props.id) {
    API.unsubscribe(prevProps.id);
    API.subscribe(this.props.id);
  }
}
componentWillUnmount() {
  API.unsubscribe(this.props.id);
}

// Hooks
useEffect(() => {
  API.subscribe(props.id);
  
  // Cleanup function (Unmount or before re-run)
  return () => API.unsubscribe(props.id);
}, [props.id]); // Dependency array acts as the conditional check

Common Pitfall: Stale Closures

Hooks capture the state *at the time of render*. If you use `setInterval`, you might see old state.

// ❌ Broken: Always prints 0
useEffect(() => {
  const id = setInterval(() => {
    console.log(count); 
  }, 1000);
  return () => clearInterval(id);
}, []); // Empty deps means 'mount only'

// ✅ Fix: Use functional state update
useEffect(() => {
  const id = setInterval(() => {
    setCount(c => c + 1); // Access latest value
  }, 1000);
  return () => clearInterval(id);
}, []);

Key Takeaways

  • Hooks encapsulate logic, not lifecycle phases.
  • Ensure dependency arrays in `useEffect` are exhaustive (use the ESLint plugin).
  • Don’t rewrite everything at once; Classes and Hooks coexist fine.

Discover more from C4: Container, Code, Cloud & Context

Subscribe to get the latest posts sent to your email.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.