React hooks, how to use “useEffect”

Sümeyra Davran
The Startup
Published in
4 min readJun 21, 2019

useEffect is one of those hooks that it’s crucial to understand how to use it

Photo by Adi Goldstein on Unsplash

Hooks are one of the important concepts in React. They have been released with React 16.8 and were aimed at solving React incapabilities.

With Hooks, you can extract stateful logic from a component so it can be tested independently and reused. Hooks allow you to reuse stateful logic without changing your component hierarchy. This makes it easy to share Hooks among many components or with the community.

As for the useEffect hook, it mainly allows you to access lifecycle methods in function components. With useEffect, you can control components re-rendering. To be precise, it can be thought as controlling componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods.

So, how do you control these lifecycle methods, or even use useEffect? To accomplish that, you need to understand the syntax.

useEffect(() => {  console.log(`I am being invoked`)}, [])

As you can see, useEffect is taking two parameters. First one is a function and second one is an array(it is also optional). In short, useEffect is invoking that function based on the second parameter. This is the useEffect’s job, strange syntax maybe but it will make sense when you understand how useEffect decides to invoke that function.

TL&DR-useEffect is making comparisons of what is inside of that array.

If the values inside the array are different, then useEffect invokes the function in re-render. Comparison is made based on Object.is method, if you want to understand behind the scene.

If you are seeing useEffect for the first time, you may think where is the second value coming from to compare? In the beginning, I told that useEffect is kind of controlling componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods.

To be complete, first value is the value that you write as initial value inside the array, it can be a string, a number, an array, or an object. This is our first value. Second value on the other hand comes when your component is re-rendered. For example, maybe you wrote a variable inside of the array and that variable was received as a prop. What happens when your prop changes? Your component re-renders.

Now that we understand where that second value comes from, let’s look at different cases. The simple case is when your value changes:

const [count, setCount] = useState(0);useEffect(() => {console.log(`I have been clicked ${count} times`);}, [count]);return (<div><button onClick={() => setCount(count + 1)}>Click me!</button></div>);

Here, we have component level state(count) and as initial value it is 0. Every time we click the button, we are updating our state and causing our component to re-render. Look at the array, count was initially 0, and every time we click, the value of the count changes. useEffect makes comparison and sees the values are different. It invokes the function. Our console will be;

// I have been clicked 0 times
// I have been clicked 1 times
// I have been clicked 2 times

If we leave the array empty;

useEffect(() => {console.log(`I have been clicked ${count} times`);}, []);// I have been clicked 0 times

Why is that? Because remember useEffect is like the combine of componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle methods. After the first render, componentDidMount takes place and useEffect invokes the function. However, when making comparison, the values are the same. They are both an empty array.

What do you think will happen if we do not give second optional parameter;

useEffect(() => {console.log(`I have been clicked ${count} times`);});
// I have been clicked 0 times

// I have been clicked 1 times

// I have been clicked 2 times

I invoked the function in every re-render. We did not pass any value and we are not checking if the value changed or not. We just invoked the function in every re-render no matter what. You can say that values inside of the array are our power to control useEffect.

One final case, despite being obvious, it may be tricky if you do not have basic comparison knowledge. What happens if we put an array or an object inside the array? How does javascript compare objects or arrays? It does it by reference, unlike primitives. If you put an object or an array, no matter what, comparison will result in different values(each object or array has its unique reference in memory) even if they are same. Keep in mind, if you put object or array, useEffect will invoke the function in every re-render.

Happy Coding!!!

--

--