Functional vs Class Components
Introduction
In React, components are the building blocks of the user interface. There are two main types of components in React: Functional Components and Class Components. Each type has its own syntax and functionality, and understanding the differences between them is essential for writing efficient, readable React code.
In this lesson, we’ll cover:
- What functional and class components are
- The main differences between them
- When to use each type
- Examples of each type of component in action
What are Functional Components?
Functional components are simple JavaScript functions that return JSX. They are primarily used to display information and don’t have a built-in state or lifecycle methods (though this changed with the introduction of hooks).
Characteristics of Functional Components
- They are written as JavaScript functions.
- They receive
props
(properties) as an argument and return JSX, which defines the UI. - They are often called “stateless components” because they traditionally didn’t have state or lifecycle methods.
Syntax of Functional Components
A functional component is a JavaScript function that returns JSX:
function Greeting(props) {
return (
<div>
<h1>Hello, {props.name}!</h1>
</div>
);
}
export default Greeting;
In this example, Greeting
is a functional component that receives props
(properties) as an argument. It displays the name passed in through props in a simple h1
element.
What are Class Components?
Class components are ES6 classes that extend from React.Component
. They are more feature-rich than functional components, as they can hold their own state and use lifecycle methods (e.g., componentDidMount
, componentDidUpdate
).
Characteristics of Class Components
- They are defined using the ES6
class
syntax and extend fromReact.Component
. - Class components have access to state and lifecycle methods, which can manage complex logic and data.
- They use a
render()
method to return JSX.
Syntax of Class Components
A class component is defined as a JavaScript class that extends React.Component
and has a render()
method:
import React, { Component } from 'react';
class Welcome extends Component {
render() {
return (
<div>
<h1>Welcome, {this.props.name}!</h1>
</div>
);
}
}
export default Welcome;
In this example, Welcome
is a class component that renders a message based on the name
prop.
Key Differences Between Functional and Class Components
Feature | Functional Components | Class Components |
---|---|---|
Syntax | Function-based syntax | Class-based syntax |
State Management | Use of hooks (useState , useEffect , etc.) |
Built-in state with this.state |
Lifecycle Methods | No lifecycle methods (can use useEffect for side effects) |
Built-in lifecycle methods (componentDidMount , componentDidUpdate , etc.) |
Code Simplicity | Simpler, concise syntax | More complex syntax with this binding |
Performance | Lighter, especially after hooks introduction | Heavier due to additional class overhead |
Hooks and Functional Components
With the introduction of hooks in React 16.8, functional components gained access to features that were previously exclusive to class components, like state and side effects. This change has led to a shift in the React community toward using functional components more frequently.
Using Props in Functional and Class Components
Props are used to pass data from a parent component to a child component.
Using Props in Functional Components
In functional components, props
are passed as an argument:
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
Using Props in Class Components
In class components, props are accessed via this.props
:
class Welcome extends React.Component {
render() {
return <h1>Welcome, {this.props.name}!</h1>;
}
}
State in Class Components vs Functional Components with Hooks
State allows components to hold and manage data that can change over time.
State in Class Components
Class components use this.state
to manage state. To update the state, you use this.setState()
:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
incrementCount = () => {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<div>
<h1>Count: {this.state.count}</h1>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
State in Functional Components with Hooks
In functional components, the useState
hook is used to manage state:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
Here, useState
initializes count
to 0
, and setCount
is a function to update count
.
Lifecycle Methods in Class Components vs useEffect
in Functional Components
Lifecycle methods in class components allow you to run code at specific points in a component's lifecycle (e.g., when a component mounts, updates, or unmounts).
Lifecycle Methods in Class Components
Class components have several lifecycle methods, such as:
- componentDidMount: Called after the component is mounted.
- componentDidUpdate: Called after the component updates.
- componentWillUnmount: Called right before the component is unmounted.
Example:
class Timer extends React.Component {
componentDidMount() {
console.log('Component mounted');
}
componentDidUpdate() {
console.log('Component updated');
}
componentWillUnmount() {
console.log('Component will unmount');
}
render() {
return <h1>Timer Component</h1>;
}
}
useEffect
Hook in Functional Components
In functional components, useEffect
can handle the same side effects as lifecycle methods:
import React, { useEffect } from 'react';
function Timer() {
useEffect(() => {
console.log('Component mounted or updated');
return () => {
console.log('Component will unmount');
};
}, []); // The empty dependency array makes it behave like componentDidMount
return <h1>Timer Component</h1>;
}
When to Use Functional Components vs Class Components
With hooks, functional components can perform most tasks that class components can, making them a popular choice. However, understanding both is beneficial, as class components are still prevalent in older React codebases.
Functional Components are Best When:
- You want a simple, lightweight component.
- You want to use hooks for state and lifecycle management.
- You prefer a concise syntax.
Class Components are Useful When:
- You’re working on a legacy codebase that uses class components.
- You’re required to use class lifecycle methods specifically.
Conclusion
In this lesson, you learned the differences between functional and class components in React. You now know:
- How to define both functional and class components
- Key distinctions in syntax, state, and lifecycle management
- How to decide which component type to use
Understanding both types of components is essential for navigating and contributing to React projects effectively. In the next lesson, we’ll dive deeper into component lifecycle methods and explore how they impact React applications.