useEffect
The fewer raw useEffect calls you have in your components, the easier you will find to maintain your application.
https://react.dev/learn/you-might-not-need-an-effect
Side Effects
A side effect is a term in functional programming that refers to when a function relies on, or modifies, something outside its "responsibility" to do something. i.e Modifying a variable or any object outside the function's scope; Printing to the console; Making network requests; etc.
In the context of React, side effects include anything that isn't "predictable" or is external to React such as fetching data from an API, interacting with browser APIs, using setTimeout/setInterval, etc. React wants us to isolate such operations from the pure rendering of a functional component using the useEffect
hook.
The useEffect
hook
useEffect
hookuseEffect
is a powerful but often misused hook.
This hook is typically used for:
making API requests (without a library) for data that your app will display when it first mounts
sending any "fire and forget" network requests like a POST request to an analytics service to log that a component was viewed
to synchronise with things outside React: browser APIs like the DOM, WebGL, Canvas, Video, and Audio and third-party widgets/libraries like D3.js, Google Charts, Maps, etc.
initialising a connection to a streaming/websocket server such as for a live chat component
useEffect
can be used in three ways (note the difference in the 2nd argument):
useEffect(() => {}, [])
empty [] means this will only run once when the Component mounts
useEffect(() => {}, [someValueToMonitor])
run on mount and then only if someValueToMonitor
has changed
useEffect(() => {})
no 2nd argument means this will run on every render/rerender
APIs and useEffect
useEffect
Fetching data from an API when a component mounts is one primary use case for useEffect
if you're not using a library or an abstraction for data fetching and state management like tanstack query or swr.
One important thing to note is that the callback function you pass to useEffect
cannot return a Promise
and therefore cannot be an async
function. You can define and/or call an async function inside the callback though.
Don't do this:
Do this:
Cleanup Function
The reason your useEffect
callback can't return a Promise
is that the hook expects a plain function as an optional return value. This returned function acts as a cleanup function and will be executed after a rerender and after the component unmounts. More detail here.
Let's say your app needs to know when the browser window is resized. The window is part of the DOM which is an external system to React so we add the event listener in a useEffect
:
The problem with the code above is that when the component the useEffect
is in is umounted, the resize event listener will still be attached to the window and will keep firing. The implications of that depends on the application but can range from inefficient to disastrous. That's what the cleanup function is for.
Remove the resize event listener when the component is unmounted:
Last updated
Was this helpful?