Belitsoft > When to Use UseUffect in React

When to Use UseUffect in React

When React developers discuss useEffect on social media, it goes with a lot of negativity, creating the impression that the hook is a buggy thing in React. However, the real reason for the problems with useEffect is that it should not be used when there is no need for it, and its valid use cases are well described and known. It's true that the useEffect hook is easy to misuse by less experienced developers. They may overuse in situations where it's not appropriate and then struggle to figure out what went wrong. However, experienced React developers don't see this as a flaw in useEffect: it's just a skill issue. The hook does exactly what it's supposed to do - just don't misuse it.

Contents

According to the React doc, Effects let you specify side effects that are caused by rendering. With Effects, you step out of your React code and synchronize with external systems like network, third-party widgets, browser APIs, and so on. 

You shouldn't use an Effect, if you just want to update a component's state when some props or state change but there is no external system involved. 

Below we look at two of these external systems in four custom React components: the network in SearchResults, ChatRoom and Form, and a third-party widget in Map.

Custom React component SearchResults

Tasks:

  1. when the component becomes visible on the screen
  2. fetch the search results from the network
  3. keep the results matching the current query and page while the component is displayed

Default React restrictions:

  1. fetching the results should happen no matter where the query came from
  2. however, fetching can't happen during rendering because it's not a calculation
  3. but there is no single event, like typing, that changes the query: it also changes from the URL or by navigating Back and Forward

What to specify in the useEffect in this case:

  1. setup code that fetches the results for the current query and page
  2. cleanup code that cancels the fetch or ignores its stale result
  3. the list of dependencies: the query and the page

How useEffect works in this case:

  1. The component is added to the page, or the query or page has changed, like the user types the next letter
  2. After the screen updates, React calls your setup function (if the query or page has changed, first the cleanup function, which marks the previous fetch as stale)
  3. Component is removed from the page, like the user navigates to another screen
  4. React calls your cleanup function

Stale results are responses that arrive after the user no longer needs them, for example, when they quickly change what they are typing. Without cleanup you would be displaying the wrong search results. With it, all responses except the last requested one are ignored.

What the React docs recommend instead of useEffect for fetching:

  1. if you use a modern React framework like Next.js, use its built-in data fetching mechanism
  2. otherwise, use a client-side cache like TanStack Query, useSWR, or React Router 6.4+. You can also build your own with logic to deduplicate requests, cache responses, and avoid network waterfalls
  3. If you still want to fetch data in Effects, extract your fetching logic into a custom Hook to decrease the number of raw useEffect calls in your components and this way improve maintainability of your application

Custom React component ChatRoom 

Tasks:

  1. when the component becomes visible on the screen
  2. connect it to the chat server
  3. keep it connected while it is displayed to the user

Default React restrictions:

  1. setting up a server connection should happen no matter which interaction caused the component to appear
  2. however, connecting to a server can't happen during rendering because it's not a calculation
  3. but there is no single particular event, like a click, that causes the component to be displayed

What to specify in the useEffect in this case:

  1. setup code that connects to the chat server
  2. cleanup code that disconnects from the chat server
  3. the list of dependencies

How useEffect works in this case:

  1. The component is added to the page, or its props and state have changed, like the user picks a different chat room
  2. After the screen updates, React calls your setup function (if props and state have changed, first the cleanup function with the old values)
  3. Component is removed from the page, like the user navigates to another screen, for example, to the Settings page
  4. React calls your cleanup function

Cleanup functions are very important and you must test that you connected them correctly. If you don't stop, undo, or clean up (disconnect, unsubscribe, cancel, ignore) whatever the setup function was doing, the connections would keep piling up, creating an easy-to-miss bug.

Custom React component Form

Tasks:

  1. when the component appears on the screen
  2. send an analytics event that the form was displayed

Default React restrictions:

  1. sending the analytics event should happen because the form was displayed to the user
  2. however, it is a POST request, not a calculation, so it can't happen during rendering
  3. but there is no particular interaction, like pressing a button, that causes the form to be displayed

What to specify in the useEffect in this case:

  1. setup code that sends the analytics event
  2. no cleanup code, because there is nothing to stop or undo once the event is sent
  3. the list of dependencies: empty, so it runs once when the form appears

How useEffect works in this case:

  1. The component is added to the page
  2. After the screen updates, React calls your setup function, which sends the analytics event

What NOT to put in the useEffect in this case:

  1. the code that sends the request when the user clicks Submit
  2. it runs because of that click, not because the form was displayed
  3. so it should be written in the event handler of the Submit button, not in the useEffect

Custom React component Map

Tasks:

  1. when the component appears on the screen
  2. add a UI map widget that isn't written in React, like Leaflet
  3. keep the widget's zoom level in sync with the zoom level in React while the component is displayed

Default React restrictions:

  1. the widget's zoom level should match the zoom level in React no matter what changed it
  2. however, the widget is a third-party library, it isn't controlled by React
  3. but the + and − buttons only change the zoom level in React, not the widget

What to specify in the useEffect in this case:

  1. setup code that calls the widget's setZoom method with the current zoom level
  2. no cleanup code is needed here: the widget doesn't start anything that keeps running, so there is nothing to stop when the component is removed.
  3. the list of dependencies: the zoom level

How useEffect works in this case:

  1. The component is added to the page, or the zoom level has changed, like the user clicks + or −
  2. After the screen updates, React calls your setup function
  3. Component is removed from the page
Never miss a post! Share it!

Written by
Chief Innovation Officer / Partner
I've been leading a department specializing in custom software development for 20 years.
0.0
0 reviews

Rate this article

Leave a comment
Your email address will not be published.

Our Clients' Feedback

Any software development, programming, or design needs we have had, Belitsoft company has always been able to handle this for us

We have been working for over 10 years and they have become our long-term technology partner. Any software development, programming, or design needs we have had, Belitsoft company has always been able to handle this for us.

We are very happy with Belitsoft

Belitsoft has been the driving force behind several of our software development projects within the last few years. This company demonstrates high professionalism in their work approach. They have continuously proved to be ready to go the extra mile. We are very happy with Belitsoft, and in a position to strongly recommend them for software development and support as a most reliable and fully transparent partner focused on long term business relationships.

We can recommend Belitsoft and are looking forward to start a follow-up project

It was a great pleasure working with Belitsoft. Software Development Company. New requirements and adjustments were implemented fast and precisely. We can recommend Belitsoft and are looking forward to start a follow-up project.

Let's Talk Business
Do you have a software development project to implement? We have people to work on it. We will be glad to answer all your questions as well as estimate any project of yours. Use the form below to describe the project and we will get in touch with you within 1 business day.
Contact form
We will process your personal data as described in the privacy notice
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply
Contact us

USA +1 (917) 410-57-57
700 N Fairfax St Ste 614, Alexandria, VA, 22314 - 2040, United States

UK +44 (20) 3318-18-53
26/28 Hammersmith Grove, London W6 7HA

Poland +48 222 922 436
Warsaw, Poland, st. Elektoralna 13/103

Email us

[email protected]

to top