Demystifying the useEffect Hook in React: A Beginner's Guide
Tags: webdev, react, beginners, frontend
Published: 2023-05-18 15:27:31

Today, we're diving into the useEffect hook, an essential tool in your React arsenal. Understanding the different ways to use useEffect will empower you to handle side effects and manage component lifecycles with confidence. 

---
### A reminder...
React components go through different stages during their existence, this is called the component lifecycle. These stages can be broadly categorized into three main phases: 
- **Mounting**: The component is created and inserted into the DOM
- **Updating**: The component is re-rendered due to changes in its props or state
- **Unmounting**: The component is removed from the DOM

---

In this blog post, we'll explore three main use cases of the useEffect hook: with an empty dependency array, with a dependency array with values and without a dependency array. Let's get started!

### 1. With an Empty Dependency Array
When you pass an empty dependency array to useEffect, it means **the effect only runs once**, when the component mounts. This is useful for performing one-time initializations or subscribing to events that don't change over time.

An use case for this can be fetching data from an API

``` jsx
import { useEffect, useState } from "react";

export default function App() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch("https://mock-api.com")
      .then((response) => response.json())
      .then((apiData) => {
        setData(apiData);
      });
  }, []);

  return (
    <div>
      {data && data.message}
    </div>
  );
}
```

In this example, the useEffect hook is used to fetch data from an API, the data is then set to the data state variable using the setData function. Since the dependency array is empty, **this piece of code will only run once when the component is mounted**.

### 2. With a Dependency Array with Values
When you provide a dependency array with specific values, **the effect runs when the component is mounted AND when those values change**. This allows you to respond to changes in the component's props or state selectively.

An use case for this could be a search functionality

``` jsx
import React, { useState, useEffect } from 'react';

function FilterableList({ items }) {
  const [filter, setFilter] = useState('');
  const [filteredItems, setFilteredItems] = useState(items);

  useEffect(() => {
    const filtered = items.filter(item => item.toLowerCase().includes(filter.toLowerCase()));
    setFilteredItems(filtered.length !== 0 ? filteredItems : items);
  }, [filter, items]);

  return (
    <div>
      <input type="text" value={filter} onChange={e => setFilter(e.target.value)} />
      <ul>
        {filteredItems.map(item => <li key={item}>{item}</li>)}
      </ul>
    </div>
  );
}
```

In this example, the useEffect hook filters a list of items based on the user's input. **The effect runs whenever the filter or items values change**, ensuring the filtered list is updated accordingly.

### 3. Without a Dependency Array
When you use the useEffect hook without providing a dependency array (_not an empty array, just no array at all_), it means **the effect will run after every render**, this means when mounting and on every update of the component due to changes in its props or state. This can lead to performance issues and unexpected behavior, especially if you're updating the state within the effect. 

_I honestly can't think of a good real life example of when to use this, in my almost 3 years of experience working with React I've never used the useEffect hook like this, if you know of a good use case please let me know in the comments!_

## Conclusion:
Congratulations! You've taken a significant step toward mastering the useEffect hook. Let's recap the key points we covered in this article:

- If you use an empty dependency array, the code block will only execute once, during component mounting
- If you pass values to the dependencies array, this will trigger the effect when the component mounts AND when the specific values within the dependency array change.
- If you use useEffect without a dependency array it will execute the code after every render.

By understanding these three main use cases of useEffect, you now have the power to handle side effects and component lifecycles efficiently. Remember to use this knowledge wisely and adapt it to your projects' needs.

Happy coding, and may your React applications thrive!