Is useEffect an alternate for ComponentDidMount?
Class-based components taught us a lot about React functionality and how it works. Two of the most used features are setState and ComponentDidMount
. Developers who switched from class-based to function-based components started using useEffect
for everything they used to do in ComponentDidMount
. Many still believe that useEffect
is a direct replacement. In this article, let's explore if this is true or not.
Initial Renders
Whenever a component is mounted, both ComponentDidMount
and useEffect
functions are called once (at least). See the below code and run it in your system -
Left is Functional Component and Right is Class Based Component. Below is the output you get -
So, both of them runs once whenever component mounts. Somewhere this is expected 😏.
Re-Renders?
Till here we have talked about “Mounting” Part. Now we are jumping on “Updating” Part. What would happen if I update something (state changes)? Would both functions trigger again? Let’s find out.
Output from Class Based Component -
Output from Functional Based Component -
Spot the difference?
When Class Based Component was ran, it first called “Constructor”, “Render Method” and then “ComponentDidMount
”. But when “setState” is called or we can say when state changes, ComponentDidMount
did not trigger itself. It’s clear that in whole component, it runs only ONCE.
On the other side, in Functional Based Component, it runs on initial render but also runs on whenever state changes (useState is called).
useEffect
doesn’t restrict itself here. useEffect accepts a callback and a DEPENDENCY ARRAY. This dependency array is game changer. But this is optional.If dependency array is not mentioned, then
useEffect
runs on every render (whenever state changes). Like wise above example.If dependency array exists but empty, then it runs only on initial render. In other words, for this scenario, it works exactly like
ComponentDidMount
.If dependency array exists, with some values, then it runs on initial render and also whenever the state of mentioned variables changes.
Catch the Updates.
We can see the difference now. But one question arises: why did the React team design useEffect
this way? There must have been something they noticed that made them realize the need for a function that can track both state changes and initial renders? Yes, there is! Let’s find out.
So, useEffect
does a lot of work -
Checks whether we have dependency array or not.
If exists, then if it’s empty or filled.
If empty, then run it only once when component mounts.
If not empty, then run on mounting and every time the state of variable changes.
When we try to implement the above in Class Based Component, it looks like below -
import React from "react";
class UserClass extends React.Component {
constructor(props) {
super(props);
this.state = {
txt: "Hello",
count: 0
}
}
componentDidMount() {
console.log("I am Component Did Mount.")
}
componentDidUpdate(prevProps, prevState) {
if(this.state.txt !== prevState.txt) {
//do something
}
if(this.state.count !== prevState.count) {
//do something
}
}
fakeButtonClick = () => {
console.log("Button is Clicked from Class")
this.setState({
txt: "Hello World"
})
}
render() {
return (
<div>
<h1>Hello! I am a Class Based Component</h1>
<button
onClick={this.fakeButtonClick}>
Click Me!
</button>
<p>{this.state.txt}</p>
</div>
)
}
}
export default UserClass;
In the code above, ComponentDidMount
runs first. Whenever we need to do something specific when a variable changes, we use ComponentDidUpdate
. This function keeps track of the previous state and props, and we check if there’s any change with the current ones. Compared to useEffect
, we just need to mention the variable name in the dependency array, and React tracks the changes automatically, reducing our work of making checks.
Class-based component code can become cluttered. Here, I added a couple of checks, but in production-ready code, there are numerous variables, arrays, and objects. Comparing them all can become a task in itself.
useEffect
function 🦾Now you know that useEffect is not exactly a replacement for ComponentDidMount. The tasks of ComponentDidMount and ComponentDidUpdate are combined into a single function, and it does even more (We will understand it in the next article). 😉
I hope you have learned something new today. If yes, give a like 😀
THANKS FOR READING UNTIL NEXT ONE 😜.
Subscribe to my newsletter
Read articles from Parmeet Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Parmeet Singh
Parmeet Singh
Hi, I am Parmeet, a Software Engineer from India. 💡 Passionate about React, JS and algorithms that dance. When I’m not debugging, you can find me jamming out to playlists or swimming. Open doors to connect and let’s create something awesome together. 🌟