React ES6 Classes
ES6 classes provide the syntax that class-based React components use to hold state and lifecycle methods.
Classes are syntax over prototypes
JavaScript has always used prototypal inheritance, but ES6 (2015) introduced the 'class' keyword as cleaner syntax over that same mechanism. A class is not a new type system — under the hood, methods still live on the prototype object, and 'new MyClass()' still creates an object whose prototype is 'MyClass.prototype'. React's older class components rely entirely on this syntax, so understanding it is essential for reading legacy React code.
A class declaration groups a constructor and a set of methods under one name. Unlike function declarations, class declarations are not hoisted in a usable way — you must define a class before referencing it.
A basic ES6 class
class Greeter {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, ${this.name}!`;
}
}
function App() {
const g = new Greeter('Ava');
console.log(g.greet()); // "Hello, Ava!"
return <p>{g.greet()}</p>;
}
export default App;
Inheritance with extends and super
The 'extends' keyword lets one class inherit from another, and 'super(...)' calls the parent constructor. This is exactly the pattern React.Component relies on: every class component extends React.Component and must call super(props) before using 'this' in its constructor.
extends and super
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound.`;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // must run before using `this`
this.breed = breed;
}
speak() {
return `${this.name} barks.`;
}
}
function App() {
const d = new Dog('Rex', 'Labrador');
console.log(d.speak()); // "Rex barks."
return <p>{d.speak()}</p>;
}
export default App;
Class components in React
Before Hooks existed (React 16.8 and earlier code), stateful components were written as classes. State lived on 'this.state', updates went through 'this.setState()', and lifecycle events like mounting or updating were separate named methods rather than useEffect calls.
A minimal class component
import React from 'react';
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
increment = () => {
this.setState((prev) => ({ count: prev.count + 1 }));
};
componentDidMount() {
console.log('Counter mounted');
}
render() {
return (
<button onClick={this.increment}>
Clicked {this.state.count} times
</button>
);
}
}
export default Counter;
Classes vs. function components
Exercise: React ES6 Classes
Why must a component class in React use `extends React.Component`?