What is Functional Component?
A functional component in React is a JavaScript function that accepts props as a parameter and returns a React element. They are also known as stateless or presentational components. Functional components were traditionally used for simpler components that did not manage their own state or lifecycle methods.
Syntax
Here’s a basic example of a functional component:
import React from 'react';
const FunctionalComponent = (props) => {
return (
<div>
<h1>Hello, {props.name}!</h1>
<p>This is a functional component.</p>
</div>
);
};
export default FunctionalComponent;
JSXExample using Hooks
With the advent of React Hooks, functional components have become even more powerful. Here’s an example of a functional component using hooks:
import React, { useState, useEffect } from 'react';
const FunctionalComponentWithHooks = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
};
export default FunctionalComponentWithHooks;
JSXIn this example:
useState
hook is used to add state to the functional component (count
state).useEffect
hook is used to perform side effects in function components. Here, it updates the document title whencount
changes.
Features and Benefits
- Simple and Concise: Functional components are straightforward JavaScript functions, making them easy to read, write, and maintain.
- No
this
Keyword: Since functional components are just functions, they don’t have athis
context. This simplifies how you write components and avoids confusion around JavaScript’sthis
keyword. - Easy to Test: Being pure functions (i.e., they depend only on their inputs and don’t modify external state), functional components are easier to test because you can test them without relying on React lifecycle methods or state changes.
- Hooks Support: With the introduction of React Hooks in React 16.8, functional components gained the ability to use state and other React features previously limited to class components. This allowed functional components to manage local state and have lifecycle behaviors using hooks like
useState
,useEffect
,useContext
, etc.
When to Use Functional Components
- Presentational Components: Functional components are perfect for presentational components that primarily render UI based on props and don’t have much internal state or complex lifecycle methods.
- Performance Considerations: Functional components are generally more lightweight compared to class components, which can lead to better performance in applications with a large number of components.
What is Class Component?
In React.js, a class component is a JavaScript class that extends React.Component
. Class components were the original way of defining components in React before the introduction of hooks. They can hold and manage local state, have access to lifecycle methods, and can provide more features compared to functional components, especially in complex scenarios.
Syntax
Here’s an example of a simple class component:
import React, { Component } from 'react';
class ClassComponent extends Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
// This lifecycle method is called after the component is mounted (inserted into the tree).
console.log('Component mounted');
}
componentDidUpdate(prevProps, prevState) {
// This lifecycle method is called after a component's state or props update.
console.log('Component updated');
}
componentWillUnmount() {
// This lifecycle method is called before the component is removed from the tree.
console.log('Component will unmount');
}
incrementCount = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
export default ClassComponent;
JSXExample Using Lifecycle Methods
Here’s an example demonstrating the use of lifecycle methods in a class component:
import React, { Component } from 'react';
class LifecycleComponent extends Component {
constructor(props) {
super(props);
this.state = {
message: 'Initial message'
};
console.log('Constructor executed');
}
componentDidMount() {
console.log('Component did mount');
}
componentDidUpdate(prevProps, prevState) {
console.log('Component did update');
}
componentWillUnmount() {
console.log('Component will unmount');
}
updateMessage = () => {
this.setState({ message: 'Updated message' });
};
render() {
console.log('Render executed');
return (
<div>
<p>{this.state.message}</p>
<button onClick={this.updateMessage}>Update Message</button>
</div>
);
}
}
export default LifecycleComponent;
JSXIn this example:
constructor
: Initializes state and performs setup tasks.componentDidMount
: Executes after the component is rendered for the first time (mounted).componentDidUpdate
: Executes after a component’s state or props update.componentWillUnmount
: Executes before the component is removed from the DOM.
Features and Benefits
- State Management: Class components have a built-in
state
object that allows them to manage local component state. State changes trigger re-rendering of the component. - Lifecycle Methods: Class components can define lifecycle methods (
componentDidMount
,componentDidUpdate
,componentWillUnmount
, etc.) that execute code at specific points in a component’s lifecycle. - Complex Logic: Class components are suitable for components that require more complex logic, state management, or need to optimize performance using lifecycle methods.
When to Use Class Components
- State Management: If your component needs to manage internal state that changes over time or needs to respond to lifecycle events (e.g., fetching data on mount, cleaning up resources on unmount), class components are still a valid choice.
- Codebase Compatibility: If you are working with an existing codebase that primarily uses class components, you may need to continue using them for consistency and compatibility reasons.
Difference Between Functional Components and Class Components
Feature | Functional Components | Class Components |
Syntax | Simple JavaScript function | ES6 classes extending ‘React.Component’ |
State Management | Uses Hooks(‘useState’,’useEffect’,etc) | Uses ‘this.state’ and ‘this.setState()’ |
LifeCycle Methods | Uses ‘useEffect’ for side effects | Uses lifecycle methods(‘componentDidMount ‘, ‘componentDidUpdate ‘, etc.) |
State Initialization | No constructor; use useState for state | Constructor initializes state |
Code Readability | Generally more concise and readable | Can be more verbose |
Performance | Lightweight; optimized re-renders with Hooks | Heavier; may require optimization strategies |
Component Structure | Functional and stateless | Class-based with state |
Flexibility | Functional components with hooks are versatile | Class components offer more traditional structure and lifecycle control |
Legacy Codebases | Can be gradually adopted with Hooks | Often used in existing codebases |
Context Usage | Uses useContext Hook for context | Context API with this.context |
Conclusion
In summary, while functional components with hooks are increasingly favored for new development in React due to their simplicity and performance advantages, class components remain relevant for certain use cases where complex state management or compatibility with older codebases is required. Understanding the strengths and limitations of each approach helps in making informed decisions when developing React applications.
Frequently Asked Questions
React Hooks are functions that let you use state and other React features in functional components. They provide a way to use local state (useState
), lifecycle methods (useEffect
), context (useContext
), and more without needing to write a class.
Prior to React Hooks, functional components did not support traditional lifecycle methods like componentDidMount
or componentDidUpdate
. Instead, hooks like useEffect
provide a more flexible way to perform side effects in functional components.
Functional components with hooks generally offer better performance due to their lightweight nature and optimized rendering. They encourage the use of pure functions and make it easier to avoid unnecessary re-renders.