Are you excited about learning React at a time when you don't need class components at all? Well, I am excited too because I would have had such a difficult time having to learn lifecycle methods like those componentDidSomething's. We are learning at such an interesting time when the React team has gone through all possible troubles to introduce React hooks. In this article, we will talk about the useEffect
Hook in particular and its role in React functional components.
The useEffect
hook gives functional components a way to synchronize with external systems, an operation that was originally possible only with class component lifecycle methods. Without too much small talk, let us get into the good stuff about the useEffect
hook. In order to use the useEffect
hooks, we need to import it from react
using the line below:
import {useEffect} from 'react'
The useEffect
hook is provided as a named export so we import it inside curly braces.
The useEffect
hook can be used to perform various tasks including ***Binding event listeners, fetching data from an external API, removing event listeners, making and canceling subscriptions, and making network requests just to mention a few. More of these tasks with deeper dives are available in the new react docs.
The syntax for calling useEffect
hook is simple, you need to call the useEffect
function with the setup code and a dependencies array.
useEffect(setupCode, dependecyArray)
The parameter setupCode
represents the code that performs a side effect and the dependencyArray
represents and array of all props and/or states that the side effect dependent on.
Depending on which tasks you need to run inside the hook and how often you want to cause there side effects, the useEffect
can be called in different ways. We will discuss the options below, beginning with calling the useEffect
hook to run a side effect only once.
Running Side Effects only once after the Initial Render
Sometimes you want to perform a particular side effect only once after the initial render and no more. Such cases can be binding an event listener to an element in the DOM. In order to run side effects only once after the initial render, we call the useEffect
hook with an empty dependency array.
useEffect(()=>{
window.addEventListener('mousemove', logMousePosition)
return ()=>{
window.removeEventListener('mousemove', logMousePosition)
}
}, [])
In the code snippet, the mousemove
event listener is added to window
once after the initial render.
Running Side Effects Conditionally
More often than not, we want to run perform side effect operations based on changes in the values of props or states or sometimes both. In this case, we need to tell React to observe specific variables for changes. If any change occurs in the values the side effect is dependent on, the setup code in the side effect is triggered. In order to achieve this, we call useEffect
with a list of dependencies.
useEffect(()=>{
document.title = `The count is ${count}`
}, [count])
This time the useEffect
hook is called with a dependency inside the dependency array. This means that the hook will always watch for changes in the value of the count
variable and if its value changes, the side document title is updated with the new value of count
.
Running Sides Effects after every Render
Take for example, you want to update and display the value of a particular variable on the screen after every second from the time of rendering to the time when the Component rendering that variable is removed from the DOM. In this case you want the effect to be cause after every re-render. In order to achieve this behavior, we call the useEffect
hook with the code we want to run but we do not define the dependency array. We do not define it all as in the code snippet below.
const tick = (counter) =>{
setCounter(() =>counter + 1)
}
console.log('call effect')
const interval = setInterval(()=> tick(counter), 1000)
})
This code snippet updates the value of count
and renders it after an interval of 1000 microseconds. This effect runs right after the first render and after all re-renders.
Cleaning Up Side Effects with useEffect
In the above code snippets, we have performed side effects and we are getting what we want. Yes we are getting what we want, but what happens to the side effects when we remove the component from the DOM? Well, this is where cleanup comes in play. Every time a component is removed from the DOM we should also revert all its side effects. Reverting side effects may include operations like canceling network requests, removing event listeners, canceling subscriptions, removing timers ect.
Cleaning up side effects may be done by returning the cleanup code inside the useEffect
function call as done in the code snippet below.
useEffect(()=>{
const tick = (counter) =>{
setCounter(() =>counter + 1)
}
console.log('call effect')
const interval = setInterval(()=> tick(counter), 1000)
return () => {clearInterval(interval)}
})
This is the same code in the previous section but this time we are adding a cleanup code to clear interval
when the component causing this effect is umounted/removed from the DOM. Keep in mind that the returned code runs only when the component firing the side effect is removed from the DOM.
That's all about useEffect
hook for today, look for more examples and practice. If you are interested in diving deeper into this, please consider looking into the docs from react team. Happy learning.
Top comments (1)
To prepare for your frontend/javascript interview. You can look at this ebook I created with collections of commonly asked frontend questions with solution.
mohit8.gumroad.com/l/ygass