Common UseEffects mistakes that even seniors are making

hernanif1

Hernani Fernandes

Posted on January 4, 2021

Common UseEffects mistakes that even seniors are making

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:

import { useEffect } from "react"
const MyComponent = () => {
  useEffect(() => {
    // do something async
  })

  return <div> Hi! </div>
}
export { MyComponent }
Enter fullscreen mode Exit fullscreen mode

now only what matters:

useEffect(() => {
    // do something async
})
Enter fullscreen mode Exit fullscreen mode

but you could also see like this:

const callbackFunction = () => { }
useEffect(callbackFunction)
Enter fullscreen mode Exit fullscreen mode

What is useEffect?

It's a function that receives two parameters, at first position a callbackFunction and at second position a dependency array:

const callbackFunction = () => { }
const dependencies = [var1,var2,...] // var1, var2,... comes from outside
useEffect(callbackFunction, dependencies)
Enter fullscreen mode Exit fullscreen mode

This callbackFunction is called:

1 - once after each render

const callbackFunction = () => { alert("2nd see this") }
useEffect(callbackFunction)
return <div>1st see this</div>
Enter fullscreen mode Exit fullscreen mode

2 - once after first render

const callbackFunction = () => { alert("2nd see this") }
useEffect(callbackFunction, []) // with an empty array [] works like the previous example
return <div>1st see this</div>
Enter fullscreen mode Exit fullscreen mode

3 - once before that component is remove from the screen

 const doSomethingBeforeDestroy = async () => { // unsubscribe }
 const callbackFunction = () => { 
   alert("2nd see this") 
   return doSomethingBeforeDestroy
 }
 useEffect(callbackFunction, []) 
 return <div>1st see this</div>
Enter fullscreen mode Exit fullscreen mode

4 - every time when dependencies variables changes it values

 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>
Enter fullscreen mode Exit fullscreen mode

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. 

Enter fullscreen mode Exit fullscreen mode

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:

const myObject = { message :"hello" }
useEffect(callbackFunction, [myObject]) 
Enter fullscreen mode Exit fullscreen mode

Do:

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)]) 
Enter fullscreen mode Exit fullscreen mode

If you use one variable but not include it inside the dependencies like this

 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>

Enter fullscreen mode Exit fullscreen mode

You will probally see the following error

React Hook useEffect has a missing dependency: 'myVar'. 
Either include it or remove the dependency array.
Enter fullscreen mode Exit fullscreen mode

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:

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
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
hernanif1
Hernani Fernandes

Posted on January 4, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related