Beginner's guide to useEffect hook in React

I am a developer from Delhi, India
Search for a command to run...

I am a developer from Delhi, India
No comments yet. Be the first to comment.
In this series, you'll learn about the basic and essential react hooks which will help you get started with functional components in ReactJS.
A key component of a web application is the state. Taken directly from the beta(new) version of the ReactJS Docs: Think of state as the minimal set of changing data that your app needs to remember. For example, if you’re building a shopping list, yo...
DISCLAIMER: This might not be the most well-written article since I haven't written in a while and I just wanted to get back to writing with a short article about my experience of the day, so sorry about that I previously used this repository for my...

The release of NextJS 13 brought about a plethora of new and impressive features, with one standout being the updated data fetching and management process. The fetch API replaced the more complicated functions, including getServerSideProps, getStatic...

Looking for a safe and reliable way to authenticate users? Consider implementing magic links. They offer a secure alternative to traditional passwords and can help mitigate the risk of password leaks and forgotten passwords. Magic Link authentication...

Neovim is a powerful text editor that can be customized with plugins to enhance its functionality. In this article, we will explore the top 10 essential Neovim plugins. These plugins can help improve your Neovim experience by adding features such as ...

A type-safe and zero-runtime version of Tailwind CSS

A few days ago, I wrote an article on how to use the useState hook. Another important hook provided by React is the useEffect hook.
Now, if you've used React Class based Components, then useEffect will help you replace functions like componentDidMount, componentDidUpdate, etc.
useEffect takes in two arguments. A function, and an array of dependencies like so:
useEffect(function, [dependencies])
Let's start with the function argument
Let's use the example I used in the useState article.
import { useState } from "react";
function App() {
const [count, setCount] = useState(1);
function incrementCount() {
setCount(count + 1);
}
return (
<div>
<h1>Hello, World</h1>
<p>{count}</p>
<button onClick={incrementCount}>Increase counter</button>
</div>
);
}
export default App;
Will give you something like this:

Now make these code:
- import { useState } from "react";
+ import { useState, useEffect } from "react";
...
const [count, setCount] = useState(1);
+ useEffect(() => {
+ console.log("useEffect running");
+ });
...
Now, go to the browser, refresh the page, open up dev tools and move to console window

Looks like it's working! But WAIT. Try clicking on the button and notice what happens:

The useEffect ran again. This is because by default, useEffect runs on every single render. When you update the state, you're basically re-rendering the component, so the useEffect runs again. This might be useful in some cases.
componentDidMountWhat if you want to run it only when the component mounts for the first time (like componentDidMount did). This is where the dependency argument comes into play. Make this change
- useEffect(() => {
- console.log("useEffect running");
- });
+ useEffect(() => {
+ console.log("useEffect running");
+ }, []);
You're passing in an empty array of dependencies. This basically means, run the useEffect loop only on first render.
There is however still one difference between this and
componentDidMount.useEffect(fn, [])runs after the first render to the DOM whereascomponentDidMountruns after "mounting" the component but before it is actually rendered(shown) in the DOM.
What if you want to run useEffect when a certain value changes. For eg. add this
const [count, setCount] = useState(1);
+ const [isDark, setIsDark] = useState(false);
...
<button onClick={incrementCount}>Increase counter</button>
+ <button onClick={() => setIsDark(!isDark)}>Toggle isDark</button>
Let's take that counter p tag to a different component for demonstration purposes
function Counter({count}) {
return <p>{count}</p>;
}
...
<div>
<h1>Hello, World</h1>
- <p>{count}</p>
+ <Counter count={count} />
...
Now say, on the Counter function, you want to take the isDark prop and every time it changes we want to send out a console.log saying that the isDark prop has changed.
First let's take the prop
- <Counter count={count} />
+ <Counter count={count} isDark={isDark} />
...
- function Counter({ count }) {
+ function Counter({ count, isDark }) {
Now, if we add a useEffect hook like this:
function Counter({ count, isDark }) {
+ useEffect(() => {
+ console.log("isDark value changed")
+ }, [isDark])
Now, you will see a console.log everytime you click on the Toggle isDark button but notice that if you click on Increase Counter, you won't see a console.log because now the useEffect runs only when the isDark value changes and not on every render like we saw before!
So, that's it for this article. Hope you take something back from this article. There's a little more to useEffect like cleaning up functions which you can read about here.
The final code for this is as follows:
import { useState, useEffect } from "react";
function App() {
const [count, setCount] = useState(1);
const [isDark, setIsDark] = useState(false);
useEffect(() => {
console.log("useEffect running");
}, []);
function incrementCount() {
setCount(count + 1);
}
return (
<div>
<h1>Hello, World</h1>
<Counter count={count} isDark={isDark} />
<button onClick={incrementCount}>Increase counter</button>
<button onClick={() => setIsDark(!isDark)}>Toggle isDark</button>
</div>
);
}
function Counter({ count, isDark }) {
useEffect(() => {
console.log("isDark value changed");
}, [isDark]);
return <p>{count}</p>;
}
export default App;