DEV Community

Felix Owino
Felix Owino

Posted on

React Hooks: Exploring the power of `useEffect` Hook.

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

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

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

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

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

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

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)

Collapse
 
moniv9 profile image
Mohit Verma

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