Class Components & Legacy Lifecycle Methods

5 questions found

What is a class component in React and how does it differ from a function component?

Beginner
A class component is written using JavaScript class syntax and extends React.Component. It manages state using this.state and this.setState, and it needs a render method that returns the JSX to display. Function components with hooks can do everything class components can, using much simpler and shorter code, which is why almost all new React code today uses function components instead.
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }
  render() {
    return (
      <button onClick={() => this.setState({ count: this.state.count + 1 })}>
        Count: {this.state.count}
      </button>
    );
  }
}
Real-world example A company maintaining an older codebase built years ago still has class components in production, even though any new features the team adds today are written as function components with hooks.

Common follow-ups: Why did the React team introduce hooks instead of continuing to improve class components?;How would you convert this class component into a function component?

Hooks;Props & State

What does componentDidMount do in a class component and what is its equivalent using hooks?

Intermediate
componentDidMount runs one time, right after a component first appears on the screen. It is commonly used to fetch data from a server or set up something like a timer. Using hooks, the same behavior is achieved with useEffect and an empty dependency array, which tells React to only run it once.
// Class component
componentDidMount() {
  fetchUserData(this.props.userId).then((data) => this.setState({ user: data }));
}

// Function component with a hook
useEffect(() => {
  fetchUserData(userId).then((data) => setUser(data));
}, []);
Real-world example An older dashboard component uses componentDidMount to load a user's profile information as soon as the page opens, exactly the same behavior a modern component would achieve with useEffect and an empty array.

Common follow-ups: What happens if you forget to pass an empty array to useEffect when trying to copy componentDidMount behavior?;What class method is used to clean something up when a component is removed from the screen?

Effects & Lifecycle;Hooks

Why can only class components be used as error boundaries in React?

Intermediate
Error boundaries need two special lifecycle methods, getDerivedStateFromError and componentDidCatch, which are only available on class components. There is currently no hook version of these methods, so even in a codebase built entirely with function components, error boundaries still need to be written as a small class component.
class ErrorBoundary extends React.Component {
  state = { hasError: false };
  static getDerivedStateFromError() {
    return { hasError: true };
  }
  render() {
    if (this.state.hasError) return <h1>Something went wrong</h1>;
    return this.props.children;
  }
}
Real-world example A modern app built entirely with function components still includes one small ErrorBoundary class component, used purely to catch and display a friendly message if any part of the app crashes unexpectedly.

Common follow-ups: Why has React not added a hook version of error boundaries yet?;What kinds of errors does an error boundary fail to catch?

Error Boundaries;Hooks

What is componentDidUpdate used for, and what mistake should you watch out for when using it?

Advanced
componentDidUpdate runs every time a component re renders after its props or state change, which makes it useful for reacting to a specific value changing, such as fetching new data when an id prop updates. A common mistake is calling setState inside it without a condition, which can trigger the component to update over and over in an endless loop.
componentDidUpdate(prevProps) {
  if (prevProps.userId !== this.props.userId) {
    this.fetchUser(this.props.userId); // only runs when userId actually changes
  }
}
Real-world example A profile page component checks whether the userId prop changed before fetching new data inside componentDidUpdate, avoiding an endless loop of unnecessary requests every time the component updates for any reason.

Common follow-ups: How would you write this same logic using useEffect with a dependency array?;What causes an infinite update loop and how do you spot one while debugging?

Effects & Lifecycle;Props & State

How do you set and update state correctly inside a class component?

Beginner
State is first defined inside the constructor using this.state as a plain object. To change it later, you always call this.setState with the new values, and React will re render the component automatically. You should never change this.state directly, since that will not trigger a re render.
class NameForm extends React.Component {
  state = { name: '' };
  handleChange = (event) => {
    this.setState({ name: event.target.value });
  };
  render() {
    return <input value={this.state.name} onChange={this.handleChange} />;
  }
}
Real-world example A simple contact form built with a class component updates the name field's value every time the user types, using this.setState to keep the input and the component's state in sync.

Common follow-ups: What happens if you try to update state by writing this.state.name directly instead of using setState?;How is updating state with setState different from updating state with the useState hook?

Props & State;Forms: Controlled & Uncontrolled Components