Common UseEffects mistakes that even seniors are making
Tags: react, javascript, hooks, frontend
Published: 2021-01-04 17:57:28

Learning useEffect in React leads us to assimilate several new concepts and for that reason we leave out small details that can cause big problems.

#### Most basic implementation:
```jsx
import { useEffect } from "react"
const MyComponent = () => {
  useEffect(() => {
    // do something async
  })

  return <div> Hi! </div>
}
export { MyComponent }
```


now only what matters:

```ts
useEffect(() => {
    // do something async
})
```

but you could also see like this:
```tsx
const callbackFunction = () => { }
useEffect(callbackFunction)
```


### **What is `useEffect`?**
It's a function that receives two parameters, at first position a callbackFunction and at second position a dependency array: 
```tsx
const callbackFunction = () => { }
const dependencies = [var1,var2,...] // var1, var2,... comes from outside
useEffect(callbackFunction, dependencies)
```

This callbackFunction is called:

1 - once after `each` render
```tsx
const callbackFunction = () => { alert("2nd see this") }
useEffect(callbackFunction)
return <div>1st see this</div>
```

2 - once after `first` render
```tsx
const callbackFunction = () => { alert("2nd see this") }
useEffect(callbackFunction, []) // with an empty array [] works like the previous example
return <div>1st see this</div>
```

3 - once before that component is `remove from the screen`
```tsx
 const doSomethingBeforeDestroy = async () => { // unsubscribe }
 const callbackFunction = () => { 
   alert("2nd see this") 
   return doSomethingBeforeDestroy
 }
 useEffect(callbackFunction, []) 
 return <div>1st see this</div>
```

4 - every time when `dependencies variables changes` it values
```tsx
 const [myVar, setMyVar] = useState("one")
 const handleClick =()=>{ 
   setMyVar("two")
 }
 const callbackFunction = () => { 
   alert("2nd see this but also after the click") 
 }
 useEffect(callbackFunction, [myVar]) 
 return <div click={handleClick}>1st see this and click</div>
```


## **Most common mistakes**:
 
#### Unsubscribe events
In example 3 you must be careful that you `should always return an asynchronous function` that `never returns a value or change to any state` because this component will be destroyed.
```
Warning: Can't perform a React state update on an unmounted component. 

```
This useEffect return is usually used to unsubscribe socket events or change the store affecting external components but never the own component.


#### Unexpected renders

In example 4 you should always (ok, not always,  there's one case that I will talk in another post) use primitives as dependencies never reference types such as *Functions, Objects or Arrays. Use only `string, boolean, number`. 

Don't:
```tsx
const myObject = { message :"hello" }
useEffect(callbackFunction, [myObject]) 
```
Do:
```tsx
const myObject = { message :"hello" }
useEffect(callbackFunction, [myObject.message])

// or 
const myObject = { message :"hello" }
useEffect(callbackFunction, [JSON.stringify(myObject.message)])  

//or 
const myArray = [1,2,3]
useEffect(callbackFunction, [JSON.stringify(myArray)]) 
```


If you use one variable but not include it inside the dependencies like this
```tsx
 const [myVar, setMyVar] = useState("one")
 const handleClick =()=>{ 
   setMyVar("two")
 }
 const callbackFunction = () => { 
   if (!myVar) setMyVar("new user")
 }
 useEffect(callbackFunction, []) // using myVar but not adding as a dependency 
 return <div click={handleClick}>1st see this and click</div>

```

You will probally see the following error
```
React Hook useEffect has a missing dependency: 'myVar'. 
Either include it or remove the dependency array.
```

Is sometimes necessary to use functions as dependencies then you should make it through `useCallback` that I will explain in my next article or simply ignore the `eslint` adding a comment like this:
```tsx 
const callbackFunction = () => { 
    if (!myVar) setMyVar("new user") 
}
useEffect(callbackFunction, [myVar]) // eslint-disable-line react-hooks/exhaustive-deps
// this comment above will ignore the error about the setMyVar function dependency
```