useEffect
was introduced in React 16.8 as a way to perform side effects in function components.
Prior to that, the only way to perform side effects in React was to use class components and lifecycle methods like componentDidMount
, componentDidUpdate
, and componentWillUnmount
.
Let’s see how we can implement useEffect inside a component for each lifecycle.
useEffect(()=>{
// componentDidMount
},[])
useEffect(()=>{
//componentDidUpdate
},[value])
useEffect(()=>{
return () => {
//componentWillUnmount
};
},[])
The first useEffect
hook is executed when the component is mounted, which is equivalent to componentDidMount
in a class-based component. The empty array at the end of the hook tells React that the effect doesn’t depend on any values from the component’s props or state, so it only needs to be executed once when the component is initially rendered.
The second useEffect
hook is executed after every update to the component, which is similar to componentDidUpdate
in a class-based component. In this case, the hook is only executed if the value changes, as indicated by the value dependency in the array at the end of the hook.
The third useEffect
hook is a bit different. It includes a return statement that specifies a cleanup function, which is executed just before the component is unmounted. This is similar to componentWillUnmount
in a class-based component.
Why useEffect runs twice in React 18
In react 18 useEffect
runs twice in development mode.You can opt out of the development behavior, but it’s recommend keeping it on.
Imagine you have a component that fetches data from an API when it mounts, and displays the data in a list. In your useEffect
hook, you call the fetchData
function to retrieve the data from the API when the component mounts.
useEffect(() => {
fetchData(); //🔴 This Effect fires twice in development.
}, []);
The first time, it will execute the code inside the hook, which in this example is a call to the fetchData
function to retrieve data from an API. The second time useEffect
runs, it will not call the fetchData
function because the hook is set up with an empty dependency array.
Running useEffect
twice in development mode can help developers catch potential issues with their code. For example, if the fetchData
function is called multiple times, it could cause the API to be hit with multiple requests, resulting in errors or slowdowns. By seeing the useEffect
hook run twice, the developer can investigate and fix the issue before deploying the app. If the useEffect
hook breaks because of the component remounting, the developer can implement a cleanup function to prevent this issue.
What is useEffect for ?
In the react documentation useEffect
is defined as
React Hook that lets you synchronize a component with an external system(third-party API, network, etc).
So as intended by the react team useEffect
must be used for synchronization.In long live effects like subscriptions useEffect can be used.
import React, { useState, useEffect } from 'react';
function Example() {
const [data, setData] = useState(null);
useEffect(() => {
// Subscribe to a data stream
const subscription = someDataStream.subscribe(data => setData(data));
// Return a cleanup function
return () => {
// Unsubscribe from the data stream
subscription.unsubscribe();
};
}, []);
// Render the component
return (
<div>
{data ? (
<p>Data: {data}</p>
) : (
<p>Loading data...</p>
)}
</div>
);
}
In this example, the useEffect
hook is called when the component is first rendered. It subscribes to a data stream and updates the component state with the latest data. The effect is only run once, because the empty array is passed as the second argument to useEffect, which tells React to only run the effect when the component is first rendered.
Whether you are a beginner or an experienced React developer, useEffect is an important hook to understand and master. By learning how to use it effectively, you can improve the performance and reliability of your React applications.
I hope this helps! Let me know if you have any other questions about what useEffect is used for in React.