Functional Components
Modern React components are plain functions. You will still meet class components in older code, so it helps to see both side by side — and to know why functions won.
On this page · 5 min · Beginner
On this page
- Learning objectives
- Explanation
- Syntax
- Code example
- Step by step
- Real-world use
- Common mistakes
- Best practices
- Remember this
- Practice exercise
- Mini quiz
- Related topics
- My notes
- Reading time
- 5 min
- Difficulty
- Beginner
- Updated
- Oct 28, 2026
Related tutorials
Learning objectives#
- Write function components with function and arrow syntax
- Compare them with class components
- Map class lifecycle and state to hooks
- Know the naming and export conventions
Explanation#
A function component takes props and returns JSX. Hooks (useState, useEffect…) give it state and side effects.
Class components (class Counter extends React.Component) use this.props, this.state, this.setState and lifecycle methods such as componentDidMount. They still work but are no longer recommended for new code.
Functions are shorter, have no this binding problems, and let you reuse logic with custom hooks instead of higher-order components or mixins.
Two syntaxes: function Card(props) { ... } or const Card = (props) => { ... }. Both are fine; function declarations hoist and show their name in DevTools.
Error boundaries are the one feature that still requires a class component (or a library like react-error-boundary).
Syntax#
// function declaration
export default function Card({ title }) { return <h2>{title}</h2>; }
// arrow function
export const Badge = ({ text }) => <span>{text}</span>;
Code example: The same counter as a class and as a function#
import { Component, useState } from 'react';
// Older style: class component
class ClassCounter extends Component {
state = { count: 0 };
increment = () => {
this.setState(prev => ({ count: prev.count + 1 }));
};
render() {
return <button onClick={this.increment}>Class: {this.state.count}</button>;
}
}
// Modern style: function component with a hook
function FunctionCounter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>Function: {count}</button>;
}
export default function Counters() {
return (
<>
<ClassCounter />
<FunctionCounter />
</>
);
}
Two buttons, “Class: 0” and “Function: 0”. Each counts its own clicks independently. Both behave the same; the function version is about half the code.
This example is illustrative. Copy or download it and run it in your own environment; the expected output is shown above.
Step-by-step explanation#
- ClassCounter stores state in this.state and changes it with this.setState.
- increment is an arrow class field so that this stays bound to the instance.
- render() returns the JSX.
- FunctionCounter gets the same behaviour from useState in three lines.
Real-world use case#
A team maintaining a 2018 React app converts class components to functions only when they change them, keeping both styles working side by side.
Common mistakes#
Hooks only work in function components and custom hooks.
onClick={this.increment} with a normal method loses this. Use arrow fields or bind in the constructor.
Class components are still supported. Migrate gradually when touching code.
Best practices#
- Write new components as functions
- Name components clearly (PascalCase)
- Keep one default export per file
- Use react-error-boundary instead of writing class boundaries
Remember this#
Function + hooks = modern React.
Class: this.state / this.setState / componentDidMount.
Function: useState / useEffect.
Practice exercise#
Your task: Convert this class component to a function component: class Hello extends Component { render() { return <p>Hello {this.props.name}</p>; } }
Need a hint?
Show solution
export default function Hello({ name = 'Asha' }) {
return <p>Hello {name}</p>;
}
Mini quiz#
How does a class component update its state?
Want more? Practise all React MCQs · React interview questions
My notes#
Saved in this browser.