React Hooks: Exploring the power of `useEffect` Hook

The React team has indeed introduced React hooks to make it easier for developers to write functional components. The useEffect Hook is one of the most important hooks in React and it allows you to perform side effects in your functional components. You can use it to fetch data, update the DOM, and more. If you want to learn more about the useEffect Hook and how it works, I recommend checking out the official React documentation. 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.

No comments:

Post a Comment