# When to Use UseUffect in React

https://belitsoft.com/when-to-use-useeffect-in-react

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
