React Function vs Class Components Explained

Function VS Class
In the world of React development, components are the building blocks of every user interface. Traditionally, developers used Class Components to manage state and lifecycle methods, but with the introduction of Hooks, Function Components have become the preferred approach for many. They offer cleaner syntax, improved readability, and easier state management without the need for boilerplate code. This article explores the key differences between Function and Class Components, helping developers understand when and why to use each approach.
Function Component
The useState
hook in React is a powerful feature that allows function components to manage internal state without relying on class-based syntax. It returns a state variable and a function to update that state, enabling dynamic behavior and reactivity within components. For example, you can track user input, toggle UI elements, or update counters—all with just a few lines of code. This simplicity and flexibility make useState
one of the most commonly used hooks in modern React development.
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
};
Class Component
In React Class Components, setState
is the method used to update a component’s state and trigger re-rendering. While it’s effective for managing dynamic data, using setState
often requires more boilerplate code—such as defining constructors, binding methods, and handling lifecycle events manually. Compared to the concise syntax of useState
in Function Components, working with setState
can feel more complex and verbose, especially when managing multiple state values or reacting to updates. This added length and structure make Class Components less favored in modern React development.
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
handleIncrease = () => {
this.setState((prevState) => ({
count: prevState.count + 1,
}));
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.handleIncrease}>Increase</button>
</div>
);
}
}
useEffect
The useEffect
hook in React is used to handle side effects in Function Components, such as fetching data, setting up subscriptions, or interacting with the DOM. It runs after the component renders and can be customized to run only once, on every update, or when specific values change—depending on the dependencies provided. This hook helps keep your code organized and reactive, making it easier to manage external interactions within your component logic.
Before useEffect
Before the introduction of the useEffect
hook in React Function Components, Class Components relied on built-in lifecycle methods to handle side effects such as data fetching, subscriptions, and DOM updates. Developers used componentDidMount
to run code after the component was first rendered, componentDidUpdate
to respond to state or prop changes, and componentWillUnmount
for cleanup tasks like clearing timers or removing event listeners. While effective, these methods often required more verbose and structured code, making Function Components with useEffect
a simpler and more flexible alternative in modern React development.
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
// useEffect(() => { ... }, [])
componentDidMount() {
console.log("Timer mounted");
this.interval = setInterval(() => {
this.setState((prev) => ({ count: prev.count + 1 }));
}, 1000);
}
// useEffect(() => { ... }, [count])
componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
console.log("Count berubah:", this.state.count);
}
}
// cleanup function in useEffect
componentWillUnmount() {
console.log("Timer akan dihapus");
clearInterval(this.interval);
}
render() {
return (
<div>
<h2>Waktu berjalan: {this.state.count} detik</h2>
</div>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = { showTimer: true };
}
toggleTimer = () => {
this.setState((prev) => ({ showTimer: !prev.showTimer }));
};
render() {
return (
<div>
<button onClick={this.toggleTimer}>Toggle Timer</button>
{this.state.showTimer && <Timer />}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Conclusion
In conclusion, understanding the differences between Function and Class Components in React is essential for writing clean, efficient, and modern code. With the advent of Hooks like useState
and useEffect
, Function Components have become the preferred choice due to their simplicity, reduced boilerplate, and improved readability. While Class Components still offer robust features through methods like setState
and lifecycle hooks, they often require more verbose syntax and structure. By embracing Function Components, developers can streamline their workflow and build reactive interfaces with greater ease.