JS: React Hooks
Theory: useEffect Hook
To carry out side effects, for example, working directly with the DOM in React, we use the built-in useEffect(). It replaces three life cycle callbacks:
componentDidMount()componentDidUpdate()componentWillUnmount()
If you forgot or didn't know how they work, you can read more about them in the official documentation.
Let's start with a simple example:
Below is an example in which the background changes with each click:
See the Pen js_react_hooks_use_effect-1 by Hexlet (@hexlet) on CodePen.
The callback passed to useEffect() is processed after the component's first rendering and after each update. In other words, we combined the componentDidUpdate() and componentDidMount() methods for convenience.
The practice using React has shown that effects occur after each render, regardless of whether this is the first or subsequent rendering. We reduced the amount of duplication in our code as a bonus.
Let us observe some typical side effects found in the front end:
- Data extraction
- Working with the BOM API (Browser Object Model), for example, Local Storage
- Direct DOM modification, this also includes libraries that are incompatible with React
Sometimes we can skip the action of the useEffect() hook. It can be helpful for optimization purposes or cases when we use the effect only under certain conditions.
To do this, we should track an array of values between renderings passed to the hook as the second argument. We trigger the callback if we change at least one value from this array.
If all values remain the same, we skip it:
In other words, we trigger the callback only when the count changes.
In the same way, you can pass any set of variables to associate them with the effect change. The effect will work when at least one variable in the passed array has changed. Otherwise, React will skip it.
How can we run useEffect() only when the first render occurs (immediately after mounting)?
To do so, you need to pass an empty array:
This solution isn't the most obvious, but technically, it is not a specific case. Someday you will get used to it.
Resetting the effect
Sometimes we need to reset. For instance, we should clean the effect up when it ceases to be relevant after changing the props.
To do this, you can return the function from useEffect() to move the cleanup inside:
Changing the userId will reset the current timer and install a new one. This code would require as many as four life cycle callbacks in classes.
We can connect the cleanup to an empty array with a second parameter to simulate componentWillUnmount():

