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
- JavaScript Class Inheritance Rules:
super()
must be called before accessingthis
- It initializes the parent class (React.Component)
- React-Specific Initialization:
super(props)
ensuresthis.props
is available in constructor- Without it,
this.props
would be undefined
Common Mistakes
- Forgetting super() entirely:
constructor(props) {
// ❌ Missing super() call
this.state = {}; // Error
}
- Accessing props before super():
constructor(props) {
// ❌ Accessing props-derived state too early
this.state = { value: props.initialValue }; // Error
super(props);
}
- Calling super() without props:
constructor(props) {
super(); // ❌ Missing props
// this.props will be undefined here
}
Best Practices
- Always call
super(props)
first if you need a constructor - Consider class fields to avoid constructor boilerplate
- 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>;
}
}