React Functional vs Class Components
React gives you two ways to write components: functional components and class components. Both produce the same result on screen, but they look different, behave differently, and have different histories in React. Today, functional components are the standard. You still encounter class components in older codebases, so knowing both is valuable.
What is a Component?
A component is a self-contained piece of your UI. Think of it like a LEGO brick — each brick has its own shape, and you combine bricks to build something larger. A React component returns JSX that describes what part of the screen it controls.
Functional Components
A functional component is a plain JavaScript function that returns JSX. It is the modern, preferred way to write React.
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
// Arrow function version (same result)
const Greeting = (props) => {
return <h1>Hello, {props.name}!</h1>;
};
Functional components are short, easy to read, and fully support all React features through hooks.
Class Components
A class component is a JavaScript class that extends React.Component. It uses a render() method to return JSX.
import React from "react";
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
Both components do the same thing — they show a greeting. The class version requires more code to achieve the same result.
Side-by-Side Comparison
Feature Functional Component Class Component
------------------------------------------------------------
Syntax Function or arrow fn ES6 class
State useState hook this.state
Lifecycle useEffect hook componentDidMount etc.
this keyword Not needed Required
Code length Short Longer
Performance Slightly better Slightly slower
Current standard YES Legacy
Handling State
State is data that can change over time inside a component. When state changes, the component re-renders.
State in a functional component
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Add</button>
</div>
);
}
State in a class component
import React from "react";
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Add
</button>
</div>
);
}
}
The functional version needs 10 lines. The class version needs 18 lines. Both counters behave identically.
Lifecycle Methods vs useEffect
Class components use specific lifecycle methods to run code at specific moments. Functional components use the useEffect hook for the same purpose.
Diagram: Lifecycle stages
MOUNTING UPDATE UNMOUNTING
| | |
Component State or props Component
added to DOM changes removed from DOM
| | |
Class: Class: Class:
componentDidMount componentDidUpdate componentWillUnmount
| | |
Function: Function: Function:
useEffect(fn, []) useEffect(fn,[dep]) useEffect(()=>{ return cleanup }, [])
One useEffect in a functional component handles what three different methods handle in a class component.
The this Problem in Class Components
Class components require using the this keyword to access props, state, and methods. The this keyword in JavaScript behaves differently depending on how a function is called, which causes bugs.
class Button extends React.Component {
handleClick() {
console.log(this); // "this" might be undefined here!
}
render() {
return <button onClick={this.handleClick}>Click</button>;
}
}
To fix this, developers had to bind methods in the constructor or use arrow functions — extra complexity that functional components avoid entirely.
When You Will See Class Components
Class components appear in:
- Projects started before React 16.8 (2019)
- Old tutorials and books written before hooks
- Error boundaries (one case where class components are still required)
New React projects use functional components exclusively. If you join an existing project with class components, you can read and maintain them without converting everything.
Should You Learn Class Components?
Focus on functional components and hooks for all new code. Learn enough class component syntax to read old code confidently. You do not need to master class components — just recognize their structure so you can work in mixed codebases.
Converting a Class Component to Functional
/* CLASS VERSION */
class Title extends React.Component {
render() {
return <h2>{this.props.text}</h2>;
}
}
/* FUNCTIONAL VERSION */
const Title = ({ text }) => <h2>{text}</h2>;
The functional version is three characters wide compared to the class version's five lines. For simple presentational components, the difference is dramatic.
Summary
Functional components are plain functions that return JSX. Class components are ES6 classes with a render() method. Both work, but functional components are shorter, easier to test, and the modern standard. Hooks like useState and useEffect give functional components all the power that class lifecycle methods provide. Write all new components as functional components and read class component code with confidence when you encounter it in older projects.
