Understanding super(props)
and State Initialization in Class Components
A common React anti-pattern is trying to access this.state
before calling super(props)
in a class component constructor. Here’s what you need to know:
The Core Issue
Incorrect (will throw an error):
class MyComponent extends React.Component {
constructor(props) {
this.state = { count: 0 }; // ❌ 'this' is not yet available
super(props);
}
}
Correct Initialization
1. Call super(props)
First (Standard Approach)
class MyComponent extends React.Component {
constructor(props) {
super(props); // ✅ Must be called first
this.state = { count: 0 };
}
}
2. Modern Class Fields Syntax (Recommended)
class MyComponent extends React.Component {
state = { count: 0 }; // ✅ No constructor needed
render() {
return <div>{this.state.count}</div>;
}
}
Why Order Matters
super()
calls the parent class constructor (React.Component)this
isn’t available until aftersuper()
completes- Props should be passed to super for proper initialization
Common Mistakes
1. Forgetting to Pass Props
constructor(props) {
super(); // ❌ Missing props
console.log(this.props); // undefined
}
2. Accessing State Too Early
constructor(props) {
this.setState({}); // ❌ Throws error
super(props);
}
3. Side Effects in Constructor
constructor(props) {
super(props);
this.fetchData(); // ❌ Avoid side effects here
}
Best Practices
- Use class fields when possible (cleaner syntax)
- Keep constructors simple – just initialization
- Move side effects to
componentDidMount
- Bind methods in constructor if needed (or use arrow functions)
Advanced Scenarios
1. Derived State from Props (Rarely Needed)
constructor(props) {
super(props);
this.state = {
derivedValue: props.initialValue * 2
};
}
2. Context Usage
constructor(props, context) {
super(props, context); // When using context
// ...
}
Migration to Functional Components
Modern React prefers hooks over class components:
function MyComponent({ initialValue }) {
const [count, setCount] = useState(0);
const derivedValue = initialValue * 2;
return <div>{count}</div>;
}
Key Takeaways
- Always call
super(props)
first in class constructors - Never access
this
beforesuper()
- Consider using class field syntax to avoid constructor issues
- In modern React, functional components with hooks are preferred