Welcome to the new post. In this post, we will learn about react useEffect hook. In a nutshell, the useeffect hook is a react hook that allows us to do tasks that are not directly related to react component rendering on UI. Let us go into detail and understand.
Inside this article:
- Introduction
- The useEffect hook syntax
- useEffect in action
- useEffect Dependencies(what to add?)
- useEffect Cleanup Function
- Conclusion
Introduction
The main function of react is to build UI, help users to interact with UI, and keep the user’s entered data(values) up to date so they can be used later to provide some feedback to the user and passed to some external service/method.
You might be thinking that then where the behaviors such as calling a service to fetch data, any kind of subscription to notify the user or do some activity, and manually updating the DOM in some scenarios goes, These are an example of side effects. Side effects are behaviors that are not directly related to react component but we need them to keep the application fully functional and React gives us a special hook called useEffect to handle these scenarios.
If you have some knowledge about the useState hook and react functional component then you may also think that why we should use another hook for the above-mentioned scenarios. The reason is if we don’t use the useEffect hook for such scenarios then, we may end up with some infinite look or some hard-to-find bugs. Let us say we are fetching some value from a service and updating the state using the useState hook, this leads the React to render the component again and which will again call the service to get the value and that will become an infinite loop until we are not doing some specific conditional handling.
The useEffect hook syntax
You should do the below steps to use the useEffect hook in your react component.
Import the useEffect from React
import {useEffect} from 'react'
Call the useEffect in your functional component as per below syntax.
useEffect([A function],[array of dependencies])
The first argument is a function that we pass to the effect hook and it is used for handling the effect scenarios (mentioned above). The second argument is optional and there you can pass dependencies, these dependencies are used by react to check whether the effect function( 1st argument ) should be triggered or not.
useEffect in action
Here is an example code. I have created a component named EffectHookExample in the components folder and added the code below.
import { useEffect } from "react";
function EffectHookExample() {
useEffect(() => {
console.log("The useEffect hook called");
});
console.log("Rendering the component");
return <h2>The Effect Hook Example Component</h2>;
}
export default EffectHookExample;
Then, I updated the App component to call the EffectHookExample as below.
import EffectHookExample from "./components/EffectHookExample";
function App() {
return (
<div>
<h2>my App</h2>
<EffectHookExample />
</div>
);
}
export default App;
Once run, we can see the below output and logs.
The Effect hook is called after the component renders which you can notice from the above output and it is called on whenever the component renders. To demo this point, let us update the EffectHookExample component code as below.
import { useEffect, useState } from "react";
function EffectHookExample() {
const [clickCount, setclickCount] = useState(0);
useEffect(() => {
console.log("The useEffect hook called");
}, [clickCount]);
function buttonClickHandler() {
setclickCount(clickCount + 1);
}
console.log("Rendering the component");
return (
<>
<button onClick={buttonClickHandler}>Clicked {clickCount} times</button>
</>
);
}
export default EffectHookExample;
Once we run the application we see the below output
Now click on the button a few times and observe the console output.
We can see in the above output we have a rendering log and then the useEffect log whenever we click on the button. This is because when we click on the button the clickCount State variable changes which trigger component re-render, following the re-render, the useEffect hook is called.
We can also use multiple useEffect to keep the component code clear and handle unrelated logic separately. Let us update the EffectHookExample component code as below.
import { useEffect, useState } from "react";
function EffectHookExample() {
const [clickCount, setclickCount] = useState(0);
const [anotherClickCount, setAnotherClickCount] = useState(0);
useEffect(() => {
console.log("The useEffect hook called for clickCount");
}, [clickCount]);
useEffect(() => {
console.log("The useEffect hook called for anotherClickCount");
}, [anotherClickCount]);
function buttonClickHandler() {
setclickCount(clickCount + 1);
}
function anotheButtonClickHandler() {
setAnotherClickCount(anotherClickCount + 1);
}
console.log("Rendering the component");
return (
<>
<button onClick={buttonClickHandler}>Clicked {clickCount} times</button>
<button onClick={anotheButtonClickHandler}>
Clicked {anotherClickCount} times
</button>
</>
);
}
export default EffectHookExample;
In the above code, you can see two useEffect one each for one state value. This is just a sample code to show that it is possible to use multiple effects same as multiple states in react.
Once run and we click on both button one by one we can see below output.
similarly, you can use the useEffect hook for side effects like calling a service to fetch data, any kind of subscription to notify the user/do some activity, and manually updating the DOM. You can read more about the useEffect hook on the official react site here.
useEffect Dependencies(what to add?)
As you have seen in the above code we added the state variable on which the Effect function is dependent for example in the below code sample, we added “anotherClickCount” as a dependency to the effect function. You should only be adding such a thing on which your effect function is dependent and not adding external variables and objects. for example, we have not added the “clickCount” state variable below the code.
useEffect(() => {
console.log("The useEffect hook called for anotherClickCount");
}, [anotherClickCount]);
useEffect Cleanup Function
The useEffect hook also provides a way to specify a cleanup function that gets executed during component clear-up activity by React. This helps us to prevent problems like a memory leaks, open database connections, and many more. Let us understand how to specify the clean-up function with an example. To demo the cleanup function I updated the code below
import { useEffect, useState } from "react";
function EffectHookExample() {
const [clickCount, setclickCount] = useState(0);
useEffect(() => {
console.log("The useEffect hook called for clickCount");
// opening database connection
console.log("Database connection opened");
return () => {
console.log("cleanup called");
console.log("Closing database connection.");
};
}, [clickCount]);
function buttonClickHandler() {
setclickCount(clickCount + 1);
}
console.log("Rendering the component");
return (
<>
<button onClick={buttonClickHandler}>Clicked {clickCount} times</button>
</>
);
}
export default EffectHookExample;
The above code is just an example to open a database connection and then close that connection during cleanup(highlighted code). Once we run the above code, you can see the output below.
Now, click on the button which will trigger the state change and that will cause the component re-render but before re-render, it should do the clean-up activity. Here is the output.
As you can see in the above output, there are logs related to the cleanup and closing of the database connection. so, the useEffect cleanup is called during component cleanup by React.
Conclusion
The useEffect is a nice hook that helps us to keep the component logic clean, handle the side effects functionality and prevent bugs that may occur due to different ways of executing functions. You should try to use this hook for the mentioned scenarios.
Thanks and Happy Learning :). Please give your valuable feedback and share this post if you liked and learned something from this post.