loading...

What is useEffect hook and how do you use it?

nibble0101 profile image Joseph Mawa ・5 min read

Alt Text

Content

  1. Introduction
  2. What arguments are passed to useEffect hook?
  3. First argument to useEffect
  4. Return value of effect
  5. Second argument to useEffect
  6. Passing a function as a dependency
  7. References

This is the third post of my react hooks series. If you haven't looked at the first two, follow the links below to look at them.

  1. What is useState hook and how do you use it?
  2. What is useReducer hook and how do you use it?

Introduction to useEffect hook.

A hook is a function which enables you use state and other react features without writing ES6 classes.
useEffect hook is part of the react hooks API. If you are familiar with react life cycles, useEffect hook is equivalent to life cycle methods componentDidMount, componentDidUpdate and componentWillUnmount combined. In fact, according to the React documentation on Hooks, useEffect hook was developed to address some of the challenges posed by life cycle methods of ES6 class components. Since this post is about what effect hook is and how it is used, i won't go into why it was developed. You can look at it Here.
In React functional components, we perform side effects such as fetching data from an API or manually updating the DOM inside the useEffect hook.

What arguments are passed to useEffect hooks?

useEffect is a function which takes two arguments. The first argument passed to useEffect is a function called effect (You can guess why this hook is named useEffect) and the second argument (which is optional) is an array of dependencies. Below is an illustration of how it is used.

import React, { useEffect } from "react";
import { render } from "react-dom";
const App = props => {
  useEffect(() => {
    console.log("Effect has been called");
  }); //Second argument to useEffect has been omitted
  return <h1> Hello world! </h1>;
};  
const root = document.getElementById("root");
render(<App />, root);

First argument to useEffect

The first argument, called effect, is a function which either returns a function (called cleanup) or undefined. effect is executed when the component is mounted (on first render) and whether it is executed in subsequent updates is determined by the array of dependencies passed as the second argument.

Return value of effect argument

From the Previous section , we said the first argument to useEffect is a function called effect. effect takes no parameters and it MUST return either a function or undefined. If it returns a function, then the function returned is called cleanup. cleanup is executed before calling effect (to clean up effects from previous render). If you are curious about why and when cleanup is necessary, look at an explanation in the React documentation. Since effect returns either a function or undefined, it is not uncommon to see effects without cleanup.

Second argument to useEffect

The second argument to useEffect is an array of dependencies . If you want to control when effect is to be executed after mounting the component, then pass an array of dependencies as the second argument. dependencies are values defined outside useEffect but are being used inside useEffect like:

     function App(){
         const[state, setState] = useState(0);
          // state is defined here
         useEffect(() => {
              console.log(state); 
              //value of state is used here therefore must be passed as a dependency
         }, [state])

     }

React compares the current value of dependency and the value on previous render. If they are not the same, effect is invoked.
This argument is optional. If you omit it, effect will be executed after every render. If you want effect to be executed only on first render, you can pass an empty array.

     useEffect(() => {
       console.log("Effect has been called");
}, []) // Empty array as dependency, useEffect is invoked once

Dependencies can be state or props. It should be noted that any value defined outside useEffect but inside the component, has to be passed as a dependency if you are to use it inside useEffect. This is illustrated below.

  function App(props) {
     const [count, setCount] = React.useState(1);
     // count and setCount are defined inside component(App) but outside useEffect
     useEffect(() => {
       //count is being used inside useEffect. Therefore must be passed as dependency.
       console.log(count);
}, [count])
}

Passing a function as a dependency

You might be wondering if you define a function outside useEffect and invoke it inside effect, do you need to pass it as a dependency?
For exampe:

 function App(props){
    const [data, setData] = useState(null);
    const fetchData = () => {
         //fetch some data 
    }
    useEffect(() => {
    fetchData(); //Invoked inside useEffect
}, [fetchData])

}

It is not recommended to define a function outside and invoke it inside effect. Above case leads to fetchData being invoked on every render because the dependency passed is a function and functions are objects. React will compare fetchData for previous and current render and the two will not be the same hence triggering a call to effect.

According to React documentation on useEffect hook,

It’s difficult to remember which props or state are used by functions outside of the effect. This is why usually you’ll want to declare functions needed by an effect inside of it. Then it’s easy to see what values from the component scope that effect depends on:

You can also move the function inside the effect so that it doesn’t need to be in its dependency list.

Thank you for reading this far. This is a brief introduction to useEffect. There are lots of things about useEffect hook i have not touched in this article. It takes some time getting used to it. If you want to deeply understand useEffect, look at the references below. If you find this article useful, share it on Twitter. Someone could find it useful too. If you find anything technically inaccurate please feel free to comment below.

REFERENCES

Posted on Jun 26 by:

nibble0101 profile

Joseph Mawa

@nibble0101

Programming noob. Learning MERN stack.

Discussion

markdown guide