React useEffect

React useEffect

The useEffect hook in React allows you to synchronize a component with an external system. It is a way to tell React that your component needs to do something after render. It accepts a callback function that contains instructions on what to do after rendering, and an array of dependencies.

The callback function will be called after the component has rendered and any time one of the dependencies has changed. The useEffect is a powerful tool that allows you to handle a wide range of tasks, from fetching data to setting up event listeners. It is similar to the lifecycle methods componentDidMount, componentDidUpdate, and componentWillUnmount in React class components.

Here's an example of using useEffect to fetch data from an API and update the component state:

import { useState, useEffect } from 'react';

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://my-api.com/data')
      .then(response => response.json())
      .then(data => setData(data))
      .catch(error => console.error(error));
  }, []); // pass an empty array as the second argument to only run the effect on mount

  return data ? <div>{data.title}</div> : <div>Loading...</div>;
}

Here's an example of using useEffect to set up an event listener and clean it up on unmount:

import { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    const handleResize = () => {
      console.log('Window resized');
    };
    window.addEventListener('resize', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []); // pass an empty array as the second argument to only run the effect on mount

  return <div>The window width is {window.innerWidth}</div>;
}

It's also possible to pass a list of dependencies as the second argument to useEffect to tell React when to re-run the effect. If the component re-renders and the dependencies haven't changed, the effect will not run again.

import { useState, useEffect } from 'react';

function MyComponent({ id }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(`https://my-api.com/data/${id}`)
      .then(response => response.json())
      .then(data => setData(data))
      .catch(error => console.error(error));
  }, [id]); 
  // This effect will only re-run if the id prop changes

  return data ? <div>{data.title}</div> : <div>Loading...</div>;
}

It's important to note that the dependencies list should only include the values that the effect function uses directly.