Accessing state before super(props) in a class component

Loading

A common React class component mistake is trying to access this.state before calling super(props) in the constructor. This causes a runtime error because the component hasn’t been properly initialized yet.

The Problem

class MyComponent extends React.Component {
  constructor(props) {
    // ❌ Wrong - accessing state before super()
    this.state = { count: 0 }; // ReferenceError

    super(props);
  }
}

Correct Solutions

1. Call super(props) First (Standard Approach)

class MyComponent extends React.Component {
  constructor(props) {
    // ✅ Correct - super() first
    super(props);

    this.state = { count: 0 };
  }
}

2. Class Property Syntax (Modern Approach)

class MyComponent extends React.Component {
  // ✅ Correct - class property syntax
  state = { count: 0 };

  // No need to write constructor at all
  render() {
    return <div>{this.state.count}</div>;
  }
}

Why This Matters

  1. JavaScript Class Inheritance Rules:
  • super() must be called before accessing this
  • It initializes the parent class (React.Component)
  1. React-Specific Initialization:
  • super(props) ensures this.props is available in constructor
  • Without it, this.props would be undefined

Common Mistakes

  1. Forgetting super() entirely:
   constructor(props) {
     // ❌ Missing super() call
     this.state = {}; // Error
   }
  1. Accessing props before super():
   constructor(props) {
     // ❌ Accessing props-derived state too early
     this.state = { value: props.initialValue }; // Error
     super(props);
   }
  1. Calling super() without props:
   constructor(props) {
     super(); // ❌ Missing props
     // this.props will be undefined here
   }

Best Practices

  1. Always call super(props) first if you need a constructor
  2. Consider class fields to avoid constructor boilerplate
  3. Avoid side effects in constructor – use componentDidMount instead

Advanced Example

class Counter extends React.Component {
  // Modern class property syntax
  state = {
    count: this.props.initialCount || 0
  };

  // Only needed if you need to process props
  constructor(props) {
    super(props); // Must come first

    // Safe to access this.props now
    this.state = {
      count: props.initialCount || 0
    };
  }

  render() {
    return <div>{this.state.count}</div>;
  }
}

Leave a Reply

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