React Hooks: useEffect
Last time I wrote about the useState hook so now I will explain what the useEffect hook does in React. The useEffect hook was developed to address some of the challenges posed by life cycle methods of ES6 class components. If you understand life cycle methods from class components, this hook is equivalent to life cycle methods componentDidMount, componentDidUpdate and componentDidUnmount. I will use an example that will show how hooks can take the place of these lifecycle methods.
First of all let’s take a look at what useEffect looks like. This hook is a function that takes in two arguments. The first is a callback with the side-effect logic inside of it. The second is an optional array of dependencies. The useEffect hook executes the callback only if the dependencies change between renderings. This allows you to control when the side-effect runs. Let’s look at what the dependencies look like and what they do.
If you don’t provide a dependency array the side-effect runs after every render.
If you provide an empty array the side-effect runs only after the initial render, similar to componentDidMount.
If you provide a state or prop value in the array the side-effect runs every time the dependency changes, similar to componentDidUpdate.
Let’s do an example with a simple program. My component will have a button that will increment a counter. After the counter reaches a certain number the document’s title will change. First let’s set up the component with the minimum. It will have a state for the counter and a handler function.
As you can see I have a useEffect function already on this component. On the components initial render ‘Mounted’ is logged on the console. When the button is clicked the number increments by 1. Perfect now let’s say we want to console log something every time the component renders but not on the initial render. The best thing about hooks is that you can have multiple ones in the same component. I will have some conditional statements to control when the effect runs. It will look like this.
I created a variable set to false that will prevent the effect from firing on the first render. After that every time the counter is incremented you will be able to see that the console prints correctly. This is because this hook did not have a dependency argument so it renders every time state changes. Now let’s implement a filter that will change the document’s title after a certain number is reached in the counter. For this I will have to use another state hook and set another conditional statement.
Now when the counter reaches 11 the document’s title is updated. This is because once the condition is met the filter state value is changed to true and the hook executes. There is one more thing we can do with useEffect. Some side-effects need cleanup, like clearing timers. If a callback returns a function then the hook will consider this as an effect cleanup.
You will see that the cleanup will run after every render. This is similar to what you can do in class components with componendDidUnmount.
I had a lot of fun learning this hook. This is one of the most important hook and also one of the trickier ones. After some practice with it though, it makes so much sense. Well, that is all for useEffect. Happy coding! 😎